CMake 库链接顺序

use*_*299 6 gcc cmake

我有以下库lib_A, lib_B, lib_C, lib_D。我在我的 CMake 文件中做这样的事情(顺序很重要):

  1. ADD_LIBRARY(lib_A)
  2. ADD_LIBRARY(lib_B)
  3. ADD_LIBRARY(lib_C)
  4. ADD_LIBRARY(lib_D)
  5. TARGET_LINK_LIBRARIES(lib_B lib_C)
  6. TARGET_LINK_LIBRARIES(lib_A lib_B)
  7. ADD_EXECUTABLE(Exec)
  8. TARGET_LINK_LIBRARIES(exec lib_A)
  9. TARGET_LINK_LIBRARIES(exec lib_D)

这导致以下链接器命令。

linker -llib_A -llib_D -llib_B -llib_C
Run Code Online (Sandbox Code Playgroud)

一季度。为什么是lib_Blib_C之后lib_D

Q2。当我稍微更改 CMake 并执行以下操作时:

  1. TARGET_LINK_LIBRARIES(lib_A lib_D)
  2. TARGET_LINK_LIBRARIES(exec lib_A)

然后链接顺序是这样的:

linker -llib_A -llib_B -llib_C -llib_D
Run Code Online (Sandbox Code Playgroud)

这里lib_Blib_C之前lib_D。这意味着target_link_libraries对于可执行目标和库目标的工作方式不同。我对吗?

这里的问题是,lib_Blib_C还取决于lib_D,但我不想做target_link_libraries(lib_B lib_D)target_link_libraries(lib_C lib_D),因为我有更多的这种情况下,我将不得不为每个库做手工。当然,在 Q2 中这样做可以解决问题,但是:

Q3 - 这个订单是由 CMake 以某种方式保证的还是只是偶然的?

谢谢

Ant*_*nio 4

只需链接lib_Blib_Cto lib_D,这是值得的(我可以根据经验判断),否则你会遇到很大的麻烦,例如,如果你尝试安装你的程序。当您完成创建其库文件后,在将它们链接到任何其他库之前,应该解决它们的所有符号lib_Clib_D

顺便说一句,您可以将target_link_libraries每个目标压缩为一行,例如:

TARGET_LINK_LIBRARIES(exec lib_A lib_D)
Run Code Online (Sandbox Code Playgroud)

而且,如果 exec 不直接依赖于,并且已正确链接到lib_D,则可以避免链接它。lib_Alib_D

无论如何,关于问题 1:即使 CMake 保证了顺序,也不能保证链接器处理它的方式,如果您依赖它,您将会遭受痛苦