【问题标题】:CMake and Static LinkingCMake 和静态链接
【发布时间】:2013-06-04 04:20:55
【问题描述】:

我在一个项目中使用 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. 我是否应该为提到的库而不是整个项目强制静态链接?

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

【问题讨论】:

    标签: gcc linker cmake static-libraries static-linking


    【解决方案1】:

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

    #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 的情况下工作,这会产生其他大问题,并且基本上可以混合静态库和动态库。

    只要静态库的顺序正确,并且只要满足静态库的依赖关系,我就可以使用一些动态库(即在我的情况下为mysqlclient,libmysql++)得到一个ELF,其余的都是静态库( 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 无法静态链接

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

    【讨论】:

    • 我得到一个“/usr/bin/ld: cannot find -lc”(在 CentOS 7 上构建)
    • @MikeM 我很难相信没有安装 C 库。也许您需要导出库路径?
    • 我最终通过 add_library(..) 硬编码了 .a 文件的路径,它对我有用(对于头文件和静态库)
    • @MikeM 如果您关心可移植性,这不是一个好的解决方案。我也很困惑为什么它找不到它,我猜你的库路径没有导出,或者 CentOS 使用了非常规的库路径?
    • 嗯,它找到了 .so 文件和标题就好了。不可能默认使用 .a 文件进行静态链接
    【解决方案2】:

    如何使用 CMake 设置静态链接

    嗯...你不知道 :) 这不是 CMake 的工作方式:在 CMake 中,您首先找到库的绝对路径,然后使用 target_link_libraries 链接到它。

    所以,如果你想链接到一个静态库,你需要搜索那个静态库:

    find_library(SOMELIB libsomelib.a)
    

    代替:

    find_library(SOMELIB somelib)
    

    【讨论】:

    • 您好!这就是我一直在做的,搜索 *.a 并获取它们。这就是我仍然得到链接错误的方式。我应该将每个静态库的绝对路径发送到链接器吗?
    • 是的,CMake 需要绝对路径,这就是 find_library 应该给你的。
    • 嗯,这就是我得到的。在运行 cmake 时,我正在记录库名称,并且可以看到完整路径和 *.a,它通常是指向实际静态库的符号链接。它仍然没有解释无参考错误,是吗?这些错误似乎来自图书馆内部。我还需要导入每个库的依赖项吗?
    • 这可能是库顺序的问题,尝试将-lmysqlclient -lmysqlpp 移动到链接器的开头,看看是否有所改善。
    • 嗯,你说对了一部分,秩序确实起到了作用。原来 -lmysqlclient 需要 -lz 到静态链接。 -lcrypto++ 也无法与 gcc.4.7.2 链接。谢谢你指出我正确的方向:-)
    猜你喜欢
    • 2017-06-13
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2022-07-15
    • 2013-03-09
    • 1970-01-01
    • 2021-10-25
    • 2015-02-09
    相关资源
    最近更新 更多