Cmake 自动向共享库的从属项添加链接选项
假设我有一个共享库,Cmake 自动向共享库的从属项添加链接选项,cmake,linker,linker-flags,Cmake,Linker,Linker Flags,假设我有一个共享库,a,还有一些与之相关的东西,B。它们在两个独立的项目中 在我当前的设置中,为了使A的功能能够正常工作,B需要将-rdynamic添加到其链接器选项中,如下所示: target_link_libraries(B -rdynamic) # mylib/CMakeLists.txt project(mylib) ... add_library(mylib SHARED ${SOURCES}) ... 问题是,A的依赖项可能很多很多,因此必须为每个依赖项显式地包含上面的行是一件麻
a
,还有一些与之相关的东西,B
。它们在两个独立的项目中
在我当前的设置中,为了使A
的功能能够正常工作,B
需要将-rdynamic
添加到其链接器选项中,如下所示:
target_link_libraries(B -rdynamic)
# mylib/CMakeLists.txt
project(mylib)
...
add_library(mylib SHARED ${SOURCES})
...
问题是,A
的依赖项可能很多很多,因此必须为每个依赖项显式地包含上面的行是一件麻烦事
有没有办法让a
的所有依赖项自动使用-rdynamic
编辑:以下是对我的情况的更详细解释 我有一个共享库,
mylib
。它不能是静态库。它在同名的CMake项目中定义
mylib
├── CMakeLists.txt
└── src
└── ...
它的CMakeLists.txt
如下所示:
target_link_libraries(B -rdynamic)
# mylib/CMakeLists.txt
project(mylib)
...
add_library(mylib SHARED ${SOURCES})
...
在单独的项目中,有一些可执行文件,client_i
,它们对mylib
使用/link,有时是间接的(即链接到链接到mylib
的内容)
其中一个CMakeLists.txt
看起来像:
# client_i/CMakeLists.txt
project(client_i)
...
add_executable(client_i ${SOME_OTHER_SOURCES})
target_link_libraries(client_i mylib -rdynamic)
...
请注意-rdynamic
。如果没有此选项,mylib
提供的某些功能将无法工作。我需要它
我的问题是可能有数千个不同的客户机,每个客户机由我提供的mylib
的不同人员/用户在自己的项目中定义(并且可以用作二进制文件)
我希望避免向每个客户端添加-rdynamic
,因为有些用户可能不知道它(因为它可能被间接使用),有些用户可能会忘记它,这可能会导致头痛等
理想情况下,mylib
的CMakeLists.txt
如下所示:
# mylib/CMakeLists.txt
project(mylib)
...
add_library(mylib SHARED ${SOURCES})
target_link_libraries(mylib -rdynamic)
...
而client\u i
CMakeLists.txt
就是:
# client_i/CMakeLists.txt
project(client_i)
...
add_executable(client_i ${SOME_OTHER_SOURCES})
target_link_libraries(client_i mylib)
...
它的链接器选项中将包含-rdynamic
。但我已经尝试过了,但它似乎不起作用。这是一个简单的解决方案,您可以尝试:
# Get a list of A's direct library dependencies.
get_target_properties(LIB_DEPENDENCIES A LINK_LIBRARIES)
# Loop through each library, adding the link option to each.
foreach(LIB ${LIB_DEPENDENCIES})
target_compile_options(${LIB} PRIVATE "-rdynamic")
endforeach()
这可以扩展,类似于@KamilCuk linked的答案,根据依赖项的多样性和复杂性来解释静态/共享/导入库和递归。当A
和B
在不同的项目中时,如何将A
与B
链接?
如果A
与B
是不同的项目,则必须打包A
并在项目B
中使用以查找A
。是一个很好的演示用例的教程。现在我们有目标链接\u选项
。您可以编写一个函数来获取a
的所有依赖库(使用likeget\u target\u属性(a LINK\u dependents…
),并将target\u LINK\u选项应用于它们中的每一个。您可以在依赖项列表上循环,只编写target\u LINK\u选项(B-rdynamic)
line once.@KamilCuk我必须使用的CMake版本没有target\u link\u选项
,但我认为还有其他选择。不过我不知道怎么才能找到所有的家属,我想我不明白。你能发布一些伪CMakeLists的例子吗?如果您有add_library(B“”)
和target_link_libraries(B-rdynamic)
,并且您有add_executable(A)
和target_link_libraries(ab)
,那么A
将与-rdynamic
选项链接。因为静态库没有链接,它们只是被压缩,链接选项接口只是传递到构建可执行文件为止。我不知道你想要什么。我相信你的问题,就像现在一样,是不清楚的,应该结束。你能用CMakeLists添加示例项目结构并说,你到底想要实现什么?我不确定这是否适合我的用例<代码>A
和B
在不同的项目中。因此,我不能在A
的CMakeLists.txt
中这样做,因为它根本不知道它的依赖项,对吗?而且,这似乎循环了A
的依赖项,而不是它的依赖项。啊,依赖项。我误解了你的问题。是的,似乎您必须在CMakeLists.txt
中为每个受抚养人(例如B
)或从您的顶级CMakeLists.txt
文件中执行此操作。@christopheddard因为它根本不知道其受抚养人,对吗?
-但受抚养人知道,并且默认情况下他们会这样做。因此,如果您的一个依赖项将链接到您,它的链接库
将使用所有依赖项链接接口库
进行填充。因此,默认情况下,它将起作用。那么你的问题是什么?我认为您应该阅读,它字面上是这样写的:目标库及其依赖项
如果您正在查找a
的依赖项,那么是的,链接库
应该为您提供您想要的。但是如果您想要一个依赖于a
(依赖项)的库/可执行文件列表,我认为您不能使用这种方法。最干净的方法可能是迭代顶级CMake中的所有目标,检查每个库的链接库
,查看是否存在A
,然后在必要时有条件地添加-rdynamic
选项。只是一个猜测,因为我们不知道项目结构的层次结构…是的,对不起,我添加了更多关于项目结构的信息。这真的不是铁板一块。没有顶级的CMake项目。