Izz*_*zzo 35 compiling c compiler libraries static-linking
假设我有一个静态main.c
链接到libmine.a
. 静态链接到库会导致库函数在编译时嵌入到主可执行文件中。
如果libmine.a
要提供 未使用的函数main.c
,编译器(例如 GCC)会丢弃这些函数吗?
这个问题的灵感来自于“常见消息传递”,即使用静态库会使可执行文件更大,所以我很好奇编译器是否至少从存档文件中删除未使用的代码。
Ste*_*itt 37
默认情况下,链接器将目标文件作为一个整体来处理。main.c
在您的示例中,可执行文件最终将包含( )中的代码main.o
,以及libmine.a
提供main.c
(传递)使用的所有函数所需的任何目标文件(目标文件的存档)。
因此链接器不一定会包含所有libmine.a
,但它可以使用的粒度是 xe2x80x99t 函数(默认情况下),它是目标文件(严格来说是节)。这样做的原因是,当给定.c
文件编译为目标文件时,源代码中的信息会丢失;特别是,函数的结尾不被存储,只存储其开始,并且由于可以组合多个函数,因此很难从目标文件中确定实际上可以删除的内容,如果某个函数未使用。
然而,如果编译器和链接器能够访问所需的额外信息,则可以做得更好。例如,\xe2\x80\x9980s Mac 上的 LightspeedC 编程环境可以使用项目作为库,并且由于在这种情况下它具有完整的源代码,因此它只会包含实际需要的功能。
\n在更现代的系统上,可以告诉编译器生成允许链接器单独处理函数的目标文件。使用 GCC,在启用选项的情况.o
下构建文件-ffunction-sections -fdata-sections
,并将最终程序与该--gc-sections
选项链接。这确实会产生影响,特别是阻止某些类别的优化;有关详细信息,请参阅丢弃 GCC 中未使用的函数。
现代编译器和链接器可以使用的另一个选项是链接时优化;启用此功能-flto
。当启用优化时(例如 -O2
编译目标文件时),链接器将不会在生成的二进制文件中包含未使用的函数。即使没有-ffunction-sections -fdata-sections
.
Whi*_*Owl 14
是的。但它是在模块级别上,而不是在功能上。
例如,您有两个源文件:foo_goo.c 和 bar.c
// foo_goo.c
int foo() { .. };
int goo() { .. };
Run Code Online (Sandbox Code Playgroud)
// bar.c
int bar() { .. };
Run Code Online (Sandbox Code Playgroud)
将它们编译成foo_goo.o
和bar.o
,并将它们.o
放入存档中libmine.a
。
现在,main()
您只调用该foo()
函数。
// main.c
int main(int argc, char **argv) {
return foo();
}
Run Code Online (Sandbox Code Playgroud)
将此源文件编译为main.o
并链接到.a
.
链接器将foo()
在模块中看到该函数foo_goo.o
并使用它,main()
将引用该foo()
函数,并且该goo()
函数将被添加到最终的二进制文件中,但不会被引用。将bar.o
被忽略,因为其中没有引用任何名称。
归档时间: |
|
查看次数: |
9482 次 |
最近记录: |