Cmake 导入的目标库和接口库之间有什么区别?

Cmake 导入的目标库和接口库之间有什么区别?,cmake,Cmake,据我所知,图书馆是这样的,非常有用。我们可以使用它来链接静态libs和传播属性 但是目标困扰着我:我看不到一个问题可以只用导入的目标来解决。当你创建导入的目标时,你告诉CMake:我已经在磁盘上的这个位置构建了这个{静态库|共享库|模块库|可执行文件}。我希望能够像对待由我自己的构建系统构建的目标一样对待它,因此请注意,当我说ImportedTargetName时,它应该引用磁盘上的二进制文件(如果适用的话,还有相关的导入库,依此类推) 当你创建一个接口库时,你告诉CMake:我有一组客户端可以

据我所知,图书馆是这样的,非常有用。我们可以使用它来链接静态libs和传播属性


但是目标困扰着我:我看不到一个问题可以只用导入的目标来解决。

当你创建导入的目标时,你告诉CMake:我已经在磁盘上的这个位置构建了这个{静态库|共享库|模块库|可执行文件}。我希望能够像对待由我自己的构建系统构建的目标一样对待它,因此请注意,当我说
ImportedTargetName
时,它应该引用磁盘上的二进制文件(如果适用的话,还有相关的导入库,依此类推)

当你创建一个接口库时,你告诉CMake:我有一组客户端可以使用的属性(包括目录等),所以如果他们“链接”到我的接口库,请将这些属性传播给他们

根本区别在于接口库没有磁盘上的任何东西作为支持,它们只是一组需求/属性。如果确实需要,可以在接口库上设置
INTERFACE\u LINK\u 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只是一个您可能希望在自定义命令中使用的示例,命令行可能不适合它)。

似乎有很多重叠。假设你在磁盘上有一个共享库和头文件,你想让它可用,这样你的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")
或者像这样:

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\u library(foo interface imported)
获得,尽管这似乎不起作用,我也不知道它是干什么用的

坦率地说,这些文档并没有真正解释你应该在图书馆中使用什么,我恐怕也不觉得Angew的“这不是他们设计的目的”很有说服力


我想两者都可以。我认为接口库更容易理解,并且与内部库中的
接口
属性的使用更一致。

@Antonio这个问题与Visual Studio的标记有什么关系?@Angew它指的是Visual Studio的属性表,我对此一无所知。虽然我知道CMake,但我不能完全理解这个问题。换句话说,要完全回答这个问题,关于VisualStudio的知识也是必要的。