我们为什么使用静态链接?

(向Plasmatic致谢,本文建立在他贴在LFS邮件列表的一篇文章基础之上。)

当写程序的时候,我们不用每次都把所有的函数重写,比如处理内核、硬件、文件等等的函数,具有一些共性。所以这些函数就保存在库文件中,供你下次写程序时使用。glibc,你后面将安装的,就是这样一个大的库文件,包含了所有基本函数供程序使用,比如打开文件,在屏幕上打印信息,从使用者得到反馈。当编译程序的时候,这些库的代码被链接到程序中,以便程序使用库提供的函数。

然而,这些库文件有可能非常大(比如libc.a经常有2.5MB大),你可能不希望在每个程序中包含一份拷贝。只要设想一下你的简单命令(比如ls)竟要附加2.5MB的库! 所以,我们不是把库作为程序的真正部份(也就是静态链接),而是把库存成单独的文件,当程序需要的时候再把它装载上来。这就是我们所说的动态链接,因为根据程序的需要,库动态地装载和卸载。

所以,现在我们有一个1KB的文件和一个2.5MB的文件,但是我们还没有节省空间。动态链接的真正优点是每个库我们只需要一份拷贝。如果lsrm都要使用同样的库,那么我们就不需要两份拷贝,因为它们都能从同一个库文件中得到所要的函数。即使在内存中,这两个程序也共享同样的代码,而不是装载两份一样的代码到内存中。所以我们不仅节约了硬盘空间,还节约了宝贵的内存。

如果动态链接节约了这么多空间,那么在这一章里我们为什么要用静态链接呢?这是因为当你使用chroot命令(在下一章里将说到)进入你崭新(但是还不完整)的LFS系统,这些动态链接的库将不能使用,因为它们放在你的老目录树中(比如/usr/lib),这样的目录在你的LFS目录树中($LFS)是不能存取的。

所以为了你的新程序能在chroot的环境下运行,你就要用静态链接来编译它们,于是--enable-static-link--disable-shared, 和-static标志在整个第五章中都要使用。一旦到了第六章,我们要做的第一件事就是重新编译glibc。做好后,我们将重新编译所有第五章的程序,但这次将用动态链接,所以最终我们能够节约空间。

这就是你必须使用那些怪异的 -static 标志的原因。如果你试图不用静态链接来编译本章的程序(千万不要这样),当你用chroot进入新系统时,你就会看到不幸的事(程序不能运行)。

如果你想了解更多动态链接库的知识,看看程序设计的书或网站,尤其是Linux相关的。