为什么我的可执行文件的.dynstr包含来自静态链接库的符号?

时间:2012-05-11 17:21:16

标签: c++ g++ static-linking

我正在构建一个C ++可执行文件。我正在静态链接我正在使用的几个C和C ++库,包括一个自定义库。 (但是,我不是静态链接我正在使用的每个库。)

即使考虑到这一点,可执行文件似乎异常大。我使用了objdump -h,它告诉我在.dynstr中使用的空间远远超出预期。我使用-Os编译并运行strip,但是当我运行

$ readelf -p .dynstr slamshift

我收到很多像

这样的条目
  [ 13588]  _ZN3yuu6windowC2Ev
  [ 1359b]  _ZTSN3yuu7gfx_ctxE
  [ 135ae]  _ZN4YAML7Scanner11ScanFlowEndEv
  [ 135ce]  __glewVertexFormatNV

我已静态链接的库中的符号(我自己的库,yaml-cpp和GLEW)。

为什么这些符号出现在我的可执行文件中?如果我已经静态链接了所涉及的库,那么符号名称不应该是不必要的吗?

我正在使用Ubuntu 12.04,GCC 4.6.3和CMake及其默认设置来构建,如果这些是相关的。

2 个答案:

答案 0 :(得分:4)

  

为什么这些符号出现在我的可执行文件中?

从可执行文件导出这些符号只有两个原因,并显示在动态符号表中。

  1. 您将可执行文件与--export-dynamic(又名-E)链接器标记或
  2. 相关联
  3. 参与该链接的其他一些共享库引用了这些符号。
  4. 如果您正在做#1,答案很简单:不要这样做。

    如果您输入了因#2而导出的符号,那么您确实希望导出符号,否则代码可能会在其他地方失败。

答案 1 :(得分:1)

一个鲜为人知的事实是,使用dl_open和朋友可以将ELF可执行文件作为动态对象打开。要使它工作,他们需要有符号导出。我认为这就是这里发生的事情。

您可以尝试使用--exclude-libs ALL向链接器执行最终程序链接。它在gcc命令行上看起来像-Wl,--exclude-libs ALL 更新:这会导致符号仍然存在,但会标记为隐藏。

您也可以尝试-Wl,--exclude-all-symbols 更新:我错了。它仅适用于PE目标。

我试过这个并且它起作用了:
gcc -static -Wl,-s export-test.c