计算机启动时接下来发生的事情是 init 被加载并运行。然而,init,像几乎所有程序一样,使用来自库的函数。
你可能见过像这样的 C 语言程序示例
main() { printf("Hello World!\n"); }
程序不包含 printf
的定义,那么它来自哪里呢?它来自标准 C 库,在 GNU/Linux 系统上是 glibc。 如果你在 Visual C++ 下编译它,那么它来自微软对相同标准函数的实现。 有大量的这些标准函数,用于数学、字符串、日期/时间、内存分配等等。 Unix(包括 Linux)中的一切要么是用 C 语言编写的,要么必须努力伪装成 C 语言,所以一切都使用这些函数。
如果你查看你的 Linux 系统上的 /lib
目录,你会看到很多名为 libsomething.so
或 libsomething.a
等的文件。 它们是这些函数的库。 Glibc 只是这些函数的 GNU 实现。
程序可以使用这些库函数有两种方式。 如果你静态链接一个程序,这些库函数会被复制到创建的可执行文件中。 这就是 libsomething.a
库的用途。 如果你动态链接一个程序(这是默认方式),那么当程序运行时需要库代码时,它会从 libsomething.so
文件中调用。
当你想 выяснить 特定程序需要哪些库时,ldd
命令是你的朋友。 例如,以下是 bash
使用的库
[greg@Curry power2bash]$ ldd /bin/bash libtermcap.so.2 => /lib/libtermcap.so.2 (0x40019000) libc.so.6 => /lib/libc.so.6 (0x4001d000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
库中的一些函数取决于你所在的位置。 例如,在澳大利亚我们把日期写成 dd/mm/yy,但美国人写成 mm/dd/yy。 glibc
发行版附带了一个名为 localedef
的程序,它可以让你设置这个。
使用 ldd
找出你最喜欢的应用程序使用了哪些库。
使用 ldd
找出 init
使用了哪些库。
创建一个玩具库,其中只有一两个函数。 程序 ar
用于创建它们,ar
的 man 手册可能是开始调查如何完成此操作的好地方。 编写、编译和链接一个使用这个库的程序。