IMPORTED目标和INTERFACE库之间有什么区别?

时间:2016-04-15 13:22:01

标签: cmake

据我所知,INTERFACE库就像Visual Studio property sheets,非常有用。我们可以使用它来链接静态库并传播属性。

IMPORTED目标让我烦恼:我无法看到只能通过IMPORTED目标解决的问题。

2 个答案:

答案 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属性更加一致。