据我所知,INTERFACE库就像Visual Studio property sheets,非常有用。我们可以使用它来链接静态库并传播属性。
但IMPORTED目标让我烦恼:我无法看到只能通过IMPORTED目标解决的问题。
答案 0 :(得分:16)
当你创建一个导入的目标时,你要告诉CMake:我有这个{静态库|共享库|模块库|已经在磁盘上的这个位置构建的可执行文件。我希望能够将它视为由我自己的构建系统构建的目标,所以请注意,当我说ImportedTargetName
时,它应该引用磁盘上的二进制文件(如果适用,则使用相关的导入库,等等上)。
当你创建一个接口库时,你告诉CMake:我有一组客户可以使用的属性(包括目录等),所以如果他们"链接"到我的界面库,请将这些属性传播给他们。
根本区别在于,接口库不受磁盘上任何内容的支持,它们只是一组需求/属性。如果您真的想要,可以在接口库上设置INTERFACE_LINK_LIBRARIES
属性,但这并不是它们的设计目的。他们将封装客户端可使用的属性,主要用于C ++中仅包含头文件库的内容。
另请注意,接口库是库 - 没有接口可执行文件,但您确实可以导入可执行文件。例如。 Bison的包配置文件可以为Bison可执行文件定义导入的目标,然后您的项目可以将其用于自定义命令:
# In Bison package config file:
add_executable(Bison IMPORTED)
set_property(TARGET Bison PROPERTY IMPORTED_LOCATION ...)
# In your project:
find_package(Bison)
add_custom_command(
OUTPUT parser.c
COMMAND Bison tab.y -o parser.c
DEPENDS tab.y
...
)
(Bison仅用作您可能希望在自定义命令中使用的示例,并且命令行可能不适合它。)
答案 1 :(得分:7)
似乎有很多重叠。假设您在磁盘上有一个共享库和标题,并且您希望它可用,以便CMake的位可以执行此操作
target_link_libraries(my_target foo)
并自动链接和获取必要的包含目录。
你可以这样做:
find_package(Foo)
add_library(foo SHARED IMPORTED)
set_target_properties(foo PROPERTIES
IMPORTED_LOCATION ${FOO_LIBRARIES} # The DLL, .so or .dylib
INTERFACE_INCLUDE_DIRECTORIES ${FOO_INCLUDE_DIR}
INTERFACE_COMPILE_DEFINITIONS "ENABLE_FOO"
)
或者像这样:
add_library(foo INTERFACE)
target_link_libraries(foo INTERFACE ${FOO_LIBRARIES})
target_include_directories(foo INTERFACE ${FOO_INCLUDE_DIR})
target_compile_definitions(foo INTERFACE "-DENABLE_FOO")
就我所知,他们的工作和行为完全相同。甚至可以通过add_library(foo INTERFACE IMPORTED)
获得“导入的界面库”,虽然这似乎不起作用,我不知道它是什么。
坦率地说,这些文档并没有真正解释你应该为图书馆使用哪些文件,而且我担心我没有找到Angew的“那不是它们的设计目的”非常引人注目。
我想要使用其中之一。我认为接口库更易于理解,并且与使用内部库中的INTERFACE
属性更加一致。