【问题标题】:cmake: ordering of shared and static libraries important?cmake:共享库和静态库的排序重要吗?
【发布时间】:2016-04-20 20:57:51
【问题描述】:

我正在创建一个二进制文件并链接依赖项。

所有二进制文件都将链接到libpthread.so
发布模式二进制文件将链接到 libtcmalloc.a

我发现库的顺序很重要。

如果我按如下方式指定对target_link_libraries 的调用,则二进制文件无法链接。

target_link_libraries(
    ${NAME} 
         ${LIBS} pthread 
    optimized
         tcmalloc_minimal.a)

错误:

[ 59%] Linking CXX executable app
.../libtcmalloc_minimal.a(libtcmalloc_minimal_internal_la-static_vars.o): 
In function `SetupAtForkLocksHandler':
    /tmp/gperftools-2.4/src/static_vars.cc:119: 
undefined reference to `pthread_atfork'

collect2: error: ld returned 1 exit status

但是,如果我更改库的顺序以使pthread 出现 tcmalloc 之后,则链接可以正常工作:

target_link_libraries(
    ${NAME} 
         ${LIBS} 
    optimized
         tcmalloc_minimal.a
    general
         pthread)

问题:

  • 有没有办法让 cmake 计算出依赖关系并自动创建正确的链接顺序?
  • gcc 有 -Wl,--start-group / -Wl,--end-group 可以解决这个问题。有没有办法让 cmake 使用这个功能?

【问题讨论】:

  • 无法提供太多具体建议,但您的观察结果是可以的:排序通常很重要,因为 TU/库是从左到右评估的,记录未定义的参考,并搜索后续单元未定义的引用。所以,家属应该放在第一位(最左边),然后是他们所依赖的东西。

标签: c++ gcc cmake


【解决方案1】:

您也可以在 cmake 中指定起始组和结束组:

target_link_libraries(${NAME} -Wl, --start-group 
  ${LIBS} optimized tcmalloc_minimal.a general pthread 
  -Wl, --end-group)

注意:虽然这是一项昂贵的操作,所以理想情况下您应该找出循环依赖关系并正确排序它们。如果这并不总是可行的,请在链接库的最小可能子集上使用 start & end 组。

【讨论】:

    【解决方案2】:

    您的问题的简短回答是:是的。链接顺序很重要。

    答案稍长;根据您的工具链,它或多或少都很重要。一些链接器只会在后面列出的库中搜索他们已经看到的符号,并且不会搜索在前面列出的库中的库中遇到的未知符号(尽管有些会)。 所以这一切都取决于你的工具。但是,无论您使用哪种工具,如果您始终注意在依赖库之前列出依赖库,那么您将愉快地与任何工具链链接(只要您没有循环依赖,即很少有工具可以处理这个问题,但大多数都不能)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-17
      • 2015-10-08
      • 1970-01-01
      • 2018-03-18
      • 2021-11-21
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      相关资源
      最近更新 更多