第5章 对链接的思考

绝大多数编译器并不是单一的庞大程序。它们通常由多达6到7个稍小的程序所组成,这些程序由一个叫做“编译器驱动器(compiler driver)”的控制程序来调用。这些可以方便地从编译器中分离出来的单独程序包括:
(1)预处理器preprocessor
(2)语法和语义检查器syntactic and semantic checker
(3)代码生成器code generator
(4)汇编程序assembler
(5)优化器optimizer
(6)链接器linker
(7)调用所有这些程序并向各个程序传递正确选项的驱动器程序driver program
优化器几乎可以加在上述所有阶段的后面。

如果函数库的一份拷贝是可执行文件的物理组成部分,那么我们称之为静态链接;如果可执行文件只是包含了文件名,让载入器在运行时能够寻找程序所需要的函数库,那么我们称之为动态链接

动态链接是一种更为现代的方法,它的优点是可执行文件的体积可以非常小。虽然运行速度稍慢一些,但动态链接能够更加有效地利用磁盘空间,而且链接-编译阶段的时间也会缩短(因为链接器的有些工作被推迟到载入时)。
动态链接的主要目的就是把程序与它们使用的特定的函数库版本中分离开来。取而代价,我们约定由系统向程序提供一个接口,该接口保持稳定,不随时间和操纵系统的后续版本发生变化。
动态链接必须保证4个特定的函数库:
(1)libc(C运行时函数库)
(2)libsys(其他系统函数)
(3)libX(X windowing)
(4)libnsl(网络服务)
其他的函数库可以通过静态链接,但最好采用动态链接。

任何人都可以创建静态或动态的函数库。只需简单地编译一些不包含main函数的代码,并把编译所生的.o文件用正确的实用工具进行处理——如果是静态库,实用ar,如果是动态库,使用ld。
静态库被称作archive,它们通过ar(用于archive的实用工具)来创建和更新。动态链接库由链接编译器ld创建。根据约定,动态库的文件扩展名为.so,表示shared object。
动态链接库的最简单形式可以通过在gcc命令上加上-G选项来创建,如:

gcc -o libfruit.so -G tomato.c

当使用函数库时,需要掌握5个基本的、不明显的约定:
(1)动态库文件的扩展名是.so,而静态库文件的扩展名为.a
(2)可通过-lthread选项,告诉编译链接到libthread.so
(3)编译器期望在确定的目录找到库
出于安全性、性能和创建/运行独立性方面的考虑,使用环境变量的做法现在已经不提倡。一般还是在链接时使用-Lpathname和-Rpathname选项。
(4)观察头文件,确认所使用的函数库
(5)与提取动态库中的符号相比,静态库中的符号提取的方法限制更严
常用库的链接编译选项为
(1)<math.h>:-lm
(2)<stdio.h>:自动链接
(3)<thread.h>:-lthread
(4)<curses.h>:-lcurses
(5)<sys/socket.h>:-lsocket
始终将-l函数库选项放在编译命令行的最右边

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值