在链接静态库时,如何将目标代码复制到可执行文件中?

Ken*_*eth 5 c linker static-libraries

我正在阅读O'Reilly的书21世纪C,其中作者声称在链接静态库时"编译器[有效地]将库的相关内容复制到最终的可执行文件中".

我试图通过创建自己的包含此模块的静态库来测试它:

static char szStr[64];

char* single_func() {
    strcpy(szStr, "Hello string!\r\n");
    return szStr;
}

void func0() {
    strcpy(szStr, "Hello");
}

char* func1() {
    strcat(szStr, " string!\r\n");
    return szStr;
}
Run Code Online (Sandbox Code Playgroud)

用于测试创建的c文件,其中一个调用single_func(),另一个调用func0()和func1().

在这两种情况下,生成的可执行文件都是751290B.如果我直接从模块调用strcpy和strcat,那么两个可执行文件最终都是7215B.

这不与上述声明冲突,还是我错过了一些关于链接的细节?

一个相关的问题是静态库是1600B,那么这个增加的大小来自哪里?


额外:

两个主文件只包括调用函数和打印结果,如下所示:

main0:

#include <stdio.h>
#include "sharedlib.h"
int main() {
    char* szStr = single_func();
    printf("%s", szStr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

MAIN1:

#include <stdio.h>
#include "sharedlib.h"
int main() {
    char* szStr;
    func0();
    szStr = func1();
    printf("%s", szStr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

文件编译如下:

gcc -static main0.c -L. -lsharedlib -o main0
Run Code Online (Sandbox Code Playgroud)

平台是linux,编译器是gcc v4.6.3.

Jon*_*ler 4

对于静态库,复制的单位是库中的目标文件。由于您的两个程序都从目标文件中调用函数,因此两个程序最终都会得到可执行文件中的所有目标文件,因此大小结果相同(给出或获取调用程序的大小main())。

可执行文件中的额外信息可能来自多个地方。其中一些是控制和调试信息。如果您也静态链接的话,其中一些可能来自 C 库。我们可能需要查看主程序和链接线,并了解平台才能提出通货膨胀的其他原因。

  • 我已经用您要求的额外信息更新了我的问题,但我想我可以开始了解这是怎么回事。1:当使用库的目标文件中的单个函数时,整个目标文件将被卷入可执行文件中。2:通过使用 -static 选项 _all_ 库被滚动到最终的可执行文件中,产生更大的文件大小。我的说法正确吗? (2认同)
  • 是的; 你在这两个细节上都是对的。如果您查看 Plauger 的书“标准 C 库”(针对 C89 标准),您会发现大多数源文件都有一个外部可见的函数,这样您就不会将不使用的内容拖到可执行文件中。您可以通过在命令行中的“-lsharedlib”之后添加“-shared”来显着减小可执行文件的大小。 (2认同)