cmake:共享和静态库的排序很重要吗?

时间:2016-04-20 20:57:51

标签: c++ gcc cmake

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

所有二进制文件都会链接到try { long endTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(30); while (true) { long timeout = Math.min( TimeUnit.SECONDS.toNanos(1), endTime - System.nanoTime()); if (timeout <= 0 || executor.awaitTermination(timeout, TimeUnit.NANOSECONDS)) { break; } System.err.println("Still waiting for timeout"); } } catch (InterruptedException e) { logger.error(e); Thread.currentThread().interrupt(); } 发布模式二进制文件将链接到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

问题:

  • cmake是否有办法计算出依赖关系并自动创建正确的链接顺序?
  • gcc有target_link_libraries( ${NAME} ${LIBS} optimized tcmalloc_minimal.a general pthread) / -Wl,--start-group解决了这个问题。有没有办法让cmake使用这个功能?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

您可以指定开始组&amp; cmake中的end-group:

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

注意:这是一项昂贵的操作,因此理想情况下,您应该找出循环依赖关系并正确排序。如果那不可能,请使用start&amp;关于链接库最小可能子集的结束组。