这篇文章说的很好:
Library order in static linking - Eli Bendersky's website (thegreenplace.net)
linker连接算法:
1、维护两个符号表:
exported table:包括linker所遇到的 .o 或 .a 导出的符号。
undefined table:包括linker所遇到的 .o 或 .a 需要的,且在前面的导出符号表中没有的符号。
2、当连接器遇到一个新的 .o 文件,无论如何都会把它链接进可执行程序:
对于它所导出符号,加到exported table,如果undefined table里有这些符号,就从undefined table里面删除这些符号,表示这些符号已经定义了,如果您exported table里有重复的符号,要报错;
对于它所需要的符号,加入undefined table里面。
3、每当连接器遇到一个新的 .a 文件(.a 文件就是简单地将.o 文件打包在一起),会选择性的将里面的.o链接进可执行程序:
遍历.a 里的每个.o ,对于每个.o,如果它导出的符号,在undefined table里有,就把它链接进可执行程序,把它导出的符号加到exported table,并且删除undefined table里对应符号,把它需要的符号,加入undefined table;如果它导出的符号没有一个在undefined table里,那这个.o 就被忽略。
如果这个.a 文件里有任何一个 .o 被链接进可执行程序,那么需要再重新扫描一遍.a里的所有.o,看看有没有哪个.o 定义了 undefined table 里所需的符号。
将静态库夹在 -Wl,--start-group 和 -Wl,--end-group 之间,可以多次次循环扫描这些库,寻找undefinded table里的符号有没有被定义。
注意:.o 文件连接时可以任意顺序,但是 .a 文件不行。