共享库的CMake和顺序依赖链接

dus*_*der 31 c++ cmake dynamic-linking

我有几个小组件,我正在构建为我的主应用程序的共享库.允许使用的一个例子libalibb.每个都在它们自己的子目录中构建,如下所示:

add_library(liba SHARED a.cpp)
Run Code Online (Sandbox Code Playgroud)

然后,在根项目文件夹中,我需要将我的主应用程序链接到两者.

include_directories(a)
include_directories(b)
add_executable(dummy dummy.cpp)
target_link_libraries(dummy a b)
Run Code Online (Sandbox Code Playgroud)

CMake运行正常,我的应用程序编译但无法链接.问题是b引用了a.如果我在链接时提供库的顺序

target_link_libraries(dummy b a)
Run Code Online (Sandbox Code Playgroud)

该程序编译和链接就好了

当这种系统开始涉及更复杂的库之间的依赖关系时,即使依赖关系是非循环的,它也开始变得不可能.如何在此管理链接步骤?在CMake中订购库以进行链接是否有诀窍?

Fra*_*ser 29

您可以指定之间的关系a,并b通过添加

target_link_libraries(b a)
Run Code Online (Sandbox Code Playgroud)


来自文档:

默认情况下,库依赖项是可传递的.当此目标链接到另一个目标时,链接到此目标的库也将出现在另一个目标的链接行上.

因此,如果您以这种方式指定a为依赖关系b,则甚至不需要a在任何依赖的目标中明确列出b,即您的其他命令可以只是:

target_link_libraries(dummy b)
Run Code Online (Sandbox Code Playgroud)

虽然它也不会对列表造成任何伤害a.

  • 如果b是当前项目未编译的外部库,该怎么办?(例如,我想将我的项目链接到依赖于pthread的jemalloc.)如果我使用`target_link_libraries(jemalloc pthread)`我会收到以下错误:`无法为目标"jemalloc"指定链接库,而不是由此项目构建的. ` (6认同)

son*_*ave 12

一个简单的解决方案(特别是对于循环依赖)可以将所有库放在一个列表变量中,然后将该列表添加两次(如果需要,可以添加更多),例如:

set(LINK_LIBS "liba libb libc")
target_link_libraries(app ${LINK_LIBS} ${LINK_LIBS})
Run Code Online (Sandbox Code Playgroud)

(或者只是在target_link_libraries函数中两次输出列表)

这对我来说已经有好几次了,但是我承认可能存在一些我不知道的缺点(除了看起来有点像黑客).