当没有调用依赖它的函数时,如何阻止库被链接?

时间:2014-03-24 01:48:48

标签: gcc linker g++ shared-libraries dynamic-linking

首先,我要创建一个小程序:

#include <gmpxx.h>

void function() {
    //mpf_class num;
    return;
}

int main() {}

请注意,我包含第三方库,但未使用其任何内容 我去编译程序:

$ g++ main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

即使我将两个额外的库链接到此程序,我也传递了标志--as-nedded,它发现在运行时实际上并不需要这两个库。因此,readelf向我们表明他们实际上没有联系。

gcc实际上将其他c和c ++库链接到除libc之外的二进制文件,但--as-needed标志发现那些文件也不需要。)

我在这里引用了库代码,但实际上并不需要它:

#include <gmpxx.h>

void function() {
    mpf_class num;
    return;
}

int main() {}

$ g++ main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libgmp.so.10]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

问题: 我假设未使用的函数被丢弃,并且不会成为二进制文件的一部分。假设编译器意识到&#34;函数&#34;代码是不需要的,并且可以抛弃它,为什么它还能意识到gmp的链接也不再需要?

有趣的是,使用完全优化运行命令

$ g++ -Ofast main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libgmp.so.10]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

导致某些gcc的隐式链接库在由于gmp包含而保留以前未经优化时被排除。

问题: 鉴于库代码永远不会被执行,编译器是否能够排除第三方库?

1 个答案:

答案 0 :(得分:1)

如果编译器绝对确定某些代码不会被使用,则允许将其丢弃。如果是这样,则呼叫不会显示在对象中,并且库已被忽略。

在未调用的示例函数中,它默认为extern,因此编译器无法知道它是否是从另一个文件调用的,并且不允许摆脱它。但是大多数编译器只是一次编译一个函数,并且很少进行函数内分析。所以我怀疑当前的编译器是否会编译该文件(使用static void function()),请注意该函数未被调用,并将其删除。也许一个聪明的连接器(进行整个程序分析)会这样做,但我没有仔细看过它。