如何链接未被使用的符号

如何链接未被使用的符号

我们知道,在ld链接静态库过程中,通常只有被使用到的符号才回被链接进可执行文件中。

而在某些场景中,我们希望在链接的时候也能把未使用的符号也给链接进来。

在ext/mylib.h文件中声明了一个add函数和一个Register对象

#pragma once

#include

int add(int a, int b);

class Register {
public:
    Register() {
        std::cout<<"Register constructor : "<<this<<std::endl;
        // register
    }
    ~Register() {}
};

在ext/mylib.cc文件中定义了add函数和一个Register静态实例

#include"mylib.h"

int add(int a, int b) {
    return a + b;
}

static Register r;

将上述文件编译成静态链接库mylib.a

在hello.cc中我们引入了mylib.h头文件,现在的问题是Register的构造函数会被调用吗?


#include"ext/mylib.h"

int main() {
    return 0;
}

第一种情况,我们虽然引入mylib.h文件,但是没有调用任何mylib中的符号。执行的结果是:


什么也没有输出,Register没有被调用,说明Register符号并没有被链接进来。

第二种情况,我们引入mylib.h文件,并且调用add函数:


#include"ext/mylib.h"

int main() {
    add(5,23);
    return 0;
}

编译运行,结果是:

Register constructor : 0x7ff8e85890e1

Register的构造函数被调用了,说明Register符号被链接进来了。

于是可以得出第一个结论,静态链接以.o文件为单位的。也就是说,在一个.o文件中,只要其中一个符号被链接进来,剩下的符号也会被链接进来(哪怕是没有被使用的)。

–whole-archive参数

如果我们没有引用链接库中的符号,但又想将这些符号链接进来怎么办?

可以使用ld链接器的一个参数:–whole-archive。具体在CMakeList中可以这么写:

target_link_libraries(my_exe -Wl,--whole-archive mylib -Wl,--no-whole-archive)

这里面需要注意的–whole-archive后面是想要全量链接的库名,之后要使用–no-whole-archive避免后面的库也全量链接。

还有一个问题,如果只想链接一个.o文件中被使用的符号,而把其它未被使用的符号删去,应该怎么做?

可以使用-ffunction-sections -fdata-sections参数生成.o文件,链接的时候再加上-Wl,–gc-sections参数。

上述实验仅针对静态链接,动态链接待研究。

你可能感兴趣的:(c++)