丢弃 GCC 中未使用的函数

rhb*_*c73 1 gcc ld

我需要一些帮助来在MinGW下使用 GCC 进行编译。

假设我有两个文件:

  • 文件ac包含两个函数,a1a2
  • 文件bc包含两个函数b1b2

然后我将这两个对象链接到一个共享库中。使用的命令如下:

gcc -c a.c
gcc -c b.c
gcc -shared -Wl, --version-script v.ver -Wl, -Map=out.map -Wl, --strip-all -o mydll.dll a.o b.o
Run Code Online (Sandbox Code Playgroud)

文件v.ver看起来像:

mylib {
   global: a1;
           a2;
   local: *;
}
Run Code Online (Sandbox Code Playgroud)

用于控制要导出哪些函数。

通过检查mapfile,我可以看到bc中的两个函数也包含在DLL文件的.text部分中。

因为这个DLL文件只导出a1a2,而b1b2只在bc中定义,但从未在任何地方使用过。我是否可以在 GCC 或ld中添加一个选项,以便b1b2不内置到 DLL 文件中,以便我可以在 DLL 文件中节省一些空间?

Che*_*ron 5

是的,这是可能的。为此,请在将 C 源代码编译为对象时添加以下两个标志:

 -ffunction-sections -fdata-sections
Run Code Online (Sandbox Code Playgroud)

这将生成更大的目标文件,但会为链接器添加大量信息。调用链接器时添加以下标志:

--gc-sections
Run Code Online (Sandbox Code Playgroud)

链接器现在将丢弃所有未使用的函数和部分。请注意,这可能会导致性能损失:

仅当这样做可以带来显着好处时才使用这些选项。当您指定这些选项时,汇编器和链接器会创建更大的目标文件和可执行文件,并且速度也会变慢。这些选项会影响代码生成。它们阻止编译器和汇编器使用翻译单元内的相对位置进行优化,因为这些位置在链接时之前是未知的。这种优化的一个例子是放宽对短调用指令的调用。( man gcc)

另请参阅此问题:Query on -ffunction-section & -fdata-sections options of gcc以获取更多信息。