2

我正在构建一个 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 及其默认设置进行构建(如果相关)。

4

2 回答 2

4

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

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

  1. 您将可执行文件与--export-dynamic(aka -E)链接器标志链接在一起,或者
  2. 参与链接的其他一些共享库引用了这些符号。

如果你在做#1,答案很简单:不要这样做。

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

于 2012-05-12T03:40:28.207 回答
1

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

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

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

我试过了,它奏效了:
gcc -static -Wl,-s export-test.c

于 2012-05-11T17:49:20.730 回答