gpt4 book ai didi

gcc - CMake 和静态链接

转载 作者:行者123 更新时间:2023-12-02 02:55:22 26 4
gpt4 key购买 nike

我在项目中使用 CMake,并且尝试静态链接一些库。我已经设置:

set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
set_target_properties(icarus PROPERTIES LINK_SEARCH_END_STATIC 1)

并且在寻找实际的库时,我已确保我拥有它们的 *.a 版本。

当前项目导入:

libPocoNet.a 
libPocoUtil.a
libPocoXML.a
libPocoFoundation.a
libmysqlclient.a
libmysqlpp.a
libcrypto++.a
CUDA

所有库都已找到,并且在进行动态/共享链接时,它们工作正常。我还尝试过设置编译标志:

set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} "-static-libgcc -static-libstdc++ -static")

但是没有效果。虽然我在编译时没有遇到任何问题,但链接对于在上述库中找到的调用抛出了很多 undefined reference 错误,即:

undefined reference to `mysql_thread_init'
undefined reference to `mysql_real_query'
undefined reference to `pthread_mutex_unlock'
undefined reference to `Poco::ErrorHandler::handle()'

不是按照特定的顺序,每个库都有很多错误。

查看 GCC 的最后一行,我看到:

/usr/bin/c++   -g -g  -static-libgcc -static-libstdc++ -static [list of *.cpp files]
-o icarus -rdynamic /usr/local/lib/libPocoFoundation.a /usr/local/lib/libPocoNet.a
/usr/local/lib/libPocoUtil.a /usr/local/lib/libPocoXML.a
-Wl,-Bstatic -lmysqlclient -lmysqlpp -lcrypto++

这让我想知道:

  1. 为什么 Poco 库链接为 -rdynamic,并且没有 -Wl -Bstatic 标志?就好像它们被跳过/排除在静态链接之外一样。
  2. mysqlclient、mysqlpp 和 crypto++ 似乎设置为静态链接,但我仍然遇到错误

那么,有人可以向我解释一下吗:

  1. 如何使用 CMake 设置部分静态链接
  2. CMAKE_EXE_LINKER_FLAGS 是我唯一需要设置的吗?
  3. 我是否应该对提到的库强制静态链接,而不是对整个项目?

如果这些问题太多或太本地化,请原谅,我以前没有尝试过,而且我似乎在网上找不到太多信息。

最佳答案

我已经通过使用以下方法解决了我的问题:

#Dynamic/Shared Libs
...
#Static start
set_target_properties(icarus PROPERTIES LINK_SEARCH_START_STATIC 1)
set_target_properties(icarus PROPERTIES LINK_SEARCH_END_STATIC 1)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
#Static Libs
...
#Set Linker flags
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")

这无需传递-static即可工作,这会产生其他大问题,并且本质上可以混合静态和动态库。

只要静态库的顺序正确,并且只要满足静态库的依赖关系,我就会得到一个使用一些动态库的ELF(即在我的例子中是mysqlclient,libmysql++),其余的都是静态库( crypto++、PocoNet、PocoUtil、PocoXML、PocoFoundation)。

请记住,静态链接库有自己的依赖项。使用 readelf -d app 检查我的调试应用程序,我发现:

Dynamic section at offset 0x508f88 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libmysqlpp.so.3]
0x0000000000000001 (NEEDED) Shared library: [libmysqlclient.so.18]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]

我知道 pthread 是由 Poco::Runnable 导入的,libm 用于数学运算等。我仍然不知道这是否是使用 CMake 进行部分静态链接的正确方法。

对于 Debian 打包库,例如 crypto++、mysql++、mysqlclient,只需找到 *.a 库就可以了,但对于 Poco Libraries,它只能获取库的完整路径和名称,但不能获取库的完整路径和名称。标志 -Bdynamic 只能通过使用上述行来关闭。

注意:如果没有 -static-libstdc++,Poco 无法静态链接

我希望这可以帮助任何遇到类似问题的人。

关于gcc - CMake 和静态链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16991225/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com