CMake中的target_link_libraries(),什么时候应该使用?

3

我刚接触CMake,希望了解一些关于target_link_libraries的细节。

如果要包含一个库,比如boost,我们可以简单地使用include_directories(BOOST_LIBRARY_PATH)。这样我的项目就能正确编译,没有错误报告。

但是在阅读一些在线文章后,我注意到人们通常会在include directories之后添加target_link_libraries(executable boost_library),所以我想知道为什么需要这行。

由于我的项目在性能方面非常敏感(即,我希望它尽可能快地运行),我的问题如下:

(1) target_link_libraries实际上是做什么的? (2) 如果我们不添加这行,会影响性能吗? (3) 包含target_link_libraries有什么优势?


target_link_libraries负责将库添加到链接器的命令行中。如果您使用某个库但未为链接器指定它,当创建可执行文件或共享库时,将会出现"undefined reference"(或"unresolved externals")错误: https://dev59.com/0Wcs5IYBdhLWcg3wym_D - undefined
@Tsyvarev 但是对于仅用于头文件的库(如boost),我们是否仍然需要添加target_link_libraries?目前看来,这行代码似乎完全多余,至少我还没有看到任何错误。 - undefined
1
哦,所以你正在使用不需要实现的头文件。(注意,整个Boost库并不是仅限于头文件:其中许多头文件在相应的库文件中有实现)。对于不需要实现的头文件,不需要使用target_link_libraries。但是Boost提供了一个名为Boost::Boost(或Boost::headers)的实用目标。使用该目标调用target_link_libraries将只添加包含目录,而不会添加库文件。 - undefined
@Tsyvarev 感谢清晰的解释。如果我理解正确的话,如果我们使用一个只包含头文件的库或者库的某些部分,include_directories 应该能正常工作。但是最好还是通过 target_link_libraries 将库链接到可执行文件,这样就不会出现奇怪的错误。但实际上它们并没有太大的区别。 - undefined
1个回答

2

target_link_libraries 根据传递的参数执行不同的操作。是否使用它取决于您要实现的具体目标。(我建议使用 target_include_directories 而不是 include_directories,因为它将包含目录的使用限制在单个目标中,并且还允许您使包含目录可用于链接 CMake 库目标,如果这些头文件在库目标的公共头文件中使用。)

  • 您可以传递库目标的名称。传递INTERFACE库目标是一种选项,可用于仅包含头文件的库。此外,对于提供cmake查找/配置脚本的已安装外部库(通常),如果正确设置,则允许您访问自动将目标的包含目录和依赖项提供给通过target_link_libraries链接到目标的目标的IMPORTED库目标。我强烈建议使用这个选项与boost一起使用。
  • 您可以传递库文件的完整路径。不过,我建议创建一个导入的库目标;虽然这可能需要更多工作,但它还允许您将信息附加到目标,例如包含目录,将相关信息放在同一位置,并且方便重用。
  • 您可以传递链接器能够找到的库的名称,例如在Linux上的target_link_libraries(executable pthread)
  • ... (我不认为这里有其他相关选项。)

在您的情况下,我的建议是:

  • 确保你已经安装了boost
  • 使用find_package+target_link_libraries来“链接”头文件库,这只是一种使头文件可用于目标的简洁方式。(我假设你使用的是仅作为头文件库而非静态或共享版本的boost库。)
find_package(Boost REQUIRED COMPONENTS headers CONFIG PATHS "/your/boost/install/path")
target_link_libraries(executable PRIVATE Boost::headers)

请注意,与使用include_directories指定输入目录相比,程序的速度不会更快或更慢;cmake配置的速度可能会有所改变,但我不建议在那里缩短任何角落。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接