据我了解INTERFACE库像Visual Studio property sheets,所以非常有用。我们可以使用它来链接静态库并传播属性。IMPORTED目标和INTERFACE库之间有什么区别?
但IMPORTED目标打扰我:我看不到只有IMPORTED目标才能解决的问题。
据我了解INTERFACE库像Visual Studio property sheets,所以非常有用。我们可以使用它来链接静态库并传播属性。IMPORTED目标和INTERFACE库之间有什么区别?
但IMPORTED目标打扰我:我看不到只有IMPORTED目标才能解决的问题。
当你创建一个导入的目标时,你告诉CMake:我有这个{静态库|共享库|模块库|可执行文件}已经构建在磁盘上的此位置。我希望能够像对待我的ons构建系统构建的目标一样对待它,所以请注意,当我说ImportedTargetName
时,它应该引用磁盘上的二进制文件(以及相关的导入库,如果适用,等等)。
当你创建一个接口库时,你告诉CMake:我有这套客户端可以使用的属性(包括目录等),所以如果他们“链接”到我的接口库,请将这些属性传播给他们。
最根本的区别是界面库不受磁盘上的任何东西的支持,它们只是一组需求/属性。你可以如果你真的想在接口库上设置INTERFACE_LINK_LIBRARIES
属性,但这不是他们真正想要的。它们将封装客户端可使用的属性,并且主要用于C++中仅包含头文件的库。
另请注意,一个接口库是一个库 —有没有接口可执行文件,但你确实可以导入可执行文件。例如。对野牛包配置文件可以定义导入目标野牛可执行文件,那么你的项目可以使用它的自定义命令:
# 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
...
)
(野牛被使用,就像你可能希望使用的一些例子自定义命令和命令行可能不正确)。
看起来好像有很多重叠。说你有磁盘上的共享库和头,并要使其可让您的CMake位可以做到这一点
target_link_libraries(my_target foo)
,并自动将其链接和获得必要的include目录。
你可以做到这一点无论是这样的:
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
的使用更加一致。
@Antonio这个问题与Visual Studio被标记为这样有什么关系? – Angew
@Angew它指的是Visual Studio属性表,其中我什么都不知道。虽然我知道CMake,但我无法完全理解这个问题。换言之,要充分回答这个问题,关于Visual Studio的知识也是必要的。 – Antonio