【问题标题】:What can linking to a CMake target impact?链接到 CMake 目标会产生什么影响?
【发布时间】:2019-06-13 02:25:39
【问题描述】:

我今天遇到了一个有趣的问题。我正在尝试编译一个测试可执行文件并将其链接到 Boost 单元测试框架,并以两种不同的方式进行了尝试。

  1. 使用-lboost_unit_test_framework 直接链接到“boost_unit_test_framework”库的经典方法
  2. 链接到Boost::unit_test_framework CMake 目标的现代 CMake 方法。

有趣的是,当我直接链接到库时,我的代码编译和链接正常;但是,当我链接到 CMake 目标时,我的代码甚至在进入链接阶段之前就无法编译!

我得到的错误与突然似乎无法再找到的头文件有关。这表明链接到 Boost::unit_test_framework 不知何故弄乱了我的包含路径。

我知道链接到 CMake 目标应该是更现代和更受欢迎的方法,但如果它会产生如此意想不到和无法解释的副作用,它似乎比直接链接到库更糟糕......

为什么链接 CMake 目标会导致找不到头文件?还有哪些其他类型的东西可以链接到 CMake 目标而不是直接链接到库影响?


在这两种情况下,我都使用target_link_libraries 链接到 boost 库。例如

target_link_libraries(mytest_exe
    testlib
    -lboost_unit_test_framework
)

target_link_libraries(mytest_exe
    testlib
    Boost::unit_test_framework
)

【问题讨论】:

  • “我的代码在进入链接阶段之前无法编译” - 请发布您的确切编译器错误。以及有关您正在使用的编译器(和版本)的信息。 minimal reproducible example 最好。
  • 你的代码只能在链接之前编译失败,链接在编译之后;)
  • 出于安全原因,我无法发布确切的编译器错误。但是,我可以声明它缺少在它使用的头文件之一中定义的内容。这应该是回答“什么可以链接到 CMake 目标影响?”的实际问题所需的所有信息。我不是在问为什么我的具体示例无法编译。我在问链接到 CMake 目标会产生什么影响。
  • @user463035818 在链接之前它失败的事实意味着 CMake 中的 target_link_libraries 命令实际上不仅仅影响链接。它也在影响编译。我的问题是为什么target_link_libraries 会影响编译?看起来不太直观。
  • 如果您无法发布原始代码的确切消息,您应该准备一个minimal reproducible example,这是非机密的并且会重现问题

标签: c++ boost cmake linker include-path


【解决方案1】:

在链接之前失败的事实意味着 CMake 中的 target_link_libraries 命令实际上影响的不仅仅是链接。它也在影响编译。

是的,当您与库 target 而不是库 file 链接时,确实会添加新的包含目录。这就是为什么该方法被称为“现代”的原因 - 单个 target_link_libraries 调用可以完成使用库所需的所有事情(在您的情况下为 Boost)。

“现代”方法失败的原因可能是“真正的”Boost 标头与您使用的其他标头冲突。您可以通过检查错误消息中的包含文件链来检测到这一点。

【讨论】:

  • 感谢@Tsyvarev,奇怪的是没有一个错误提到任何boost头文件,甚至在调用target_link_libraries之前和之后打印包含路径列表也会产生相同的路径列表。在这一点上,我仍然不确定它修改了什么,但我会继续朝这个方向寻找。
  • 嗯,我不确定,但unit_test_framework 不仅可以添加包含目录,还可以编译定义。 (与目标链接可能会修改几乎所有编译器选项)。实际上,您可以比较两种情况下的编译器命令行,看看有什么不同。
  • 好主意!我将在这两种情况下运行 make VERBOSE=1 并比较输出以查看哪些标志和编译器选项可能不同
  • 解决了!果然它正在修改包含路径,它将其中一个移动到包含路径列表的后面。这不应该是个问题,但有些笨蛋认为将include_directories(".") 放在我们所有代码都使用的主 CMake 脚本中是个好主意。这导致我的当前目录被视为“系统”目录。这意味着#include <someheader.h> 在我自己的项目中查找someheader.h 并在它应该只在系统头文件中查找它时将其拉入...
猜你喜欢
  • 2010-12-23
  • 2010-11-28
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-23
相关资源
最近更新 更多