我们可以动态地链接编译的静态库

时间:2016-02-20 18:02:42

标签: c++

demo_lib.h     void fun();

demo_lib.cpp

#include<iostream>
void fun(){
    std::cout << "I am in demo_lib::fun()" << std::endl;
}

编译了一个静态库

g++ -c demo_lib.cpp -o demo_lib.o
ar rcs libdemo_lib.a demo_lib.a

的main.c

#include "demo_lib.h"
int main(){
    fun();
    return 0;
}

编译静态

g++ -static main.cpp -L. -ldemo_lib
size of a.out is 1702697 => static linked by linker 

没有静态编译

g++ main.cpp -L. -ldemo_lib
size of a.out is 9247  => is demo_lib linked dynamically  ??

为什么这里的大小不同?

我认为当我们使用-static编译器选项

时,cpp库是静态链接的

当我们没有cpp库是动态链接的,除了demo_lib。

在这两种情况下,demo_lib都是静态链接,只有cpp库diff

我们可以将静态编译库链接为动态吗?

这是否意味着共享标准库的默认链接?

2 个答案:

答案 0 :(得分:4)

您在--static之间看到的大小差异是C和C ++标准库函数是否已链接。因此,大小差异不是来自您的库(可能只是几百个字节,因为它只是对cout::operator<<()的几次调用,并且应该仅产生大约十几个指令[假设x86,但在ARM或MIPS上它将是不超过20-25个指令所有代码]。

不,你不能静态链接共享库,也不能将静态库链接为共享 - 它们是具有不同内容的不同文件。当您使用--static时,编译器(或链接器)将优先选择X.a而不是X.so [假设两者都存在]。

添加-Wl,--verbose将显示[或至少比没有更多细节]链接器在您链接程序时所执行的操作,并且会在--static之间清楚地显示差异。使用--static,您将得到一大堆行:

(/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64/libc.a)read.o
在这种情况下,

表示函数read [这是freadscanfcin::operator>>等基础的基础。

您当然也可以使用objdump -d来查看与您的应用程序相关联的代码,例如。

答案 1 :(得分:1)

除了优秀的Mats Petersson答案之外,还有一个很好的工具可以检查动态链接的库数量,只需输入

> ldd a.out

并且输出将包含您的应用链接到的所有共享库