gcc 链接合并过程



E 将被合并以组成可执行文件的所有目标文件集合
U 当前所有未解析的引用符号的集合
D 当前所有定义符号的集合

/* my.lib */ 

#include <stdio.h> 

void foo() 

   printf("%s","I am from mylib!\n"); 



/* main.obj*/*/ 

void foo(); 

int main() 

   foo(); 
   return 0; 


编译,然后用 

link main.obj my.lib 

    一开始 E 、 U 、 D 都是空集,链接器首先扫描到 main.obj ,把它加入 E 集合,同时把未解析的 foo 加入 U ,把 main 加入 D ,而且因为 main.obj 的默认标准库是 libc.lib ,所以它被加入到当前输入文件列表的末尾。

接着扫描 my.lib ,因为这是个库,所以会拿当前 U 中的所有符号 ( 当然现在就一个 foo) 与 my.lib 中的所有目标模块 ( 当然也只有一个 mylib.obj) 依次匹配,看是否有模块定义了 U 中的符号。

结果 my.lib  确实定义了 foo ,于是它被加入到 E , foo 从 U 转移到 D , my.lib 引用的 printf 加入到 U ,同样地, my.lib 指定的默认标准库是 libcd.lib ,它也被加到当前输入文件列表的末尾 ( 在 libc.lib 的后面 ) 。

不断地在 my.lib 库的各模块上进行迭代以匹配 U 中的符号,直到 U 、 D 都不再变化。很明显,现在就已经到达了这么一个不动点,所以接着扫描下一个输入文件,就是 libc.lib 。

链接器发现 libc.lib 里的 printf.obj 里定义有 printf ,于是 printf 从 U 移到 D ,而 printf.obj 被加入到 E ,它定义的所有符号加入到 D ,它里头的未解析符号加入到 U 。

链接器还会把每个程序都要用到的一些初始化操作所在的目标模块 ( 比如 crt0.obj 等 ) 及它们所引用的模块 ( 比如 malloc.obj 、 free.obj 等 ) 自动加入到 E 中,并更新 U 和 D 以反应这个变化。

事实上,标准库各目标模块里的未解析符号都可以在库内其它模块中找到定义,因此当链接器处理完 libc.lib 时, U 一定是空的。最后处理 libcd.lib ,因为此时 U 已经为空,

所以链接器会抛弃它里面的所有目标模块从而结束扫描,然后合并 E 中的目标模块并输出可执行文件。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值