将库作为最后一个目标与所有目标链接

3
我正在为我的项目添加对gperftools的支持,以进行CPU和内存分析。Gperftools需要将库tcmalloc链接到每个二进制文件时最后
是否有一种方法可以使用CMake向我的项目中的所有二进制目标附加一个库,而无需编辑每个CMakeLists.txt
我在这里找到了一个类似的问题:link library to all targets in cmake project,但它没有得到解答。建议通过宏来解决问题,但并没有说明如何实现这一点。

1
你问道cmake是否有一种方法...,而你所提到的问题有一个评论没有内置的方法可以去除这个。这只是对你问题的回答。或者你更喜欢一个正式的回答(不是评论)? - Tsyvarev
它说没有内置的方法,但为宏等替代方式打开了一扇门。我正在考虑这种方式,但还不知道如何正确地实现。 - Falco
1
我认为你应该首先收集所有现有目标的列表。不幸的是,这是CMake中另一个没有内置功能 https://cmake.org/pipermail/cmake/2011-January/042079.html。不过,似乎你可以覆盖标准的`add_library`命令 https://cmake.org/pipermail/cmake/2010-September/039388.html。 - Antonio
2
请问您是否可以添加CMake代码片段,展示您尝试过哪些内容以及哪些已经适用于单一目标? 一种可能的方法是,在覆盖add_executable()之外,修改/扩展 CMAKE_CXX_LINK_EXECUTABLE, CMAKE_CXX_IMPLICIT_LINK_LIBRARIESCMAKE_STANDARD_LIBRARIES - Florian
1个回答

6

正如@Florian所建议的,您可以使用CMAKE_CXX_STANDARD_LIBRARIES变量来链接每个目标的库作为system,因此它将有效地成为链接列表中的last

关于此变量有几点需要注意:

  1. 与CMake文档中所写的不同,该变量名称包含<LANG>前缀。

  2. 在使用此变量时,期望附加库的完整路径,如果附加库不在LD_LIBRARY_PATH下,则可执行文件将无法工作,并显示Cannot open shared object file error错误。对于我来说,使用C编译器(和相应的前缀在变量名称中),link_directories()有帮助。对于C++,只有RPATH设置有帮助。

例如:

CMakeLists.txt:

# Assume path to the additional library is <a-dir>/<a-filename>
set(CMAKE_CXX_STANDARD_LIBRARIES <a-dir>/<a-filename>)
set(CMAKE_INSTALL_RPATH <a-dir>)

add_executable(hello hello.cpp)
install(TARGETS hello DESTINATION bin)

hello.cpp:

#include <stdlib.h>
int main(void)
{
    void p = malloc(10);
    if(p) free(p);
}

假设有一个额外的库替换了malloc函数,那么可执行文件将使用该替换。在Linux上使用CMake 2.8和3.4进行测试(Makefile生成器)。更新:如@Falco所建议的,在gcc编译器中,可以使用-l:前缀指定附加库。
set(CMAKE_CXX_STANDARD_LIBRARIES -l:<full-library-path>)

使用这样的前缀gcc将使用给定库的完整路径链接可执行文件,因此可执行文件将在不需要额外RPATH设置的情况下正常工作。


这个解决方案可行且符合我的需求。您可以通过以下方式进行改进:set(CMAKE_CXX_STANDARD_LIBRARIES -l:<a-dir>/<a-filename>) 。 "-l:"使gcc链接到完整路径的库,这避免了在系统路径中拥有该库或将其添加到LD_LIBRARY_PATH的需要。 - Falco
谢谢你的提示,我已经将它添加到帖子中了。 - Tsyvarev

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