彻底理解链接器:一,前言
在介绍本章的主题之前,我们先来看几个问题:
问题一
写C/C++的同学应该经常遇到这样的一个Error:
"undefined reference to ABC"
在遇到这样的问题时你知道这背后到底哪里出问题了吗? 你通常都能顺利解决类似问题吗?
问题二
作为世界上最大的同性交友网站GitHub,里面有很多很棒的项目,一般我们或者直接下载其发布版(release version),或者下载源码自己编译,不管是直接下载发布版还是自己编译,最终都会得到一个(或几个)以.so或者.a为结尾的文件(Windows下为DLL文件或者lib文件),这时你知道该怎么把这些.so或者.a文件引入你自己的项目吗?当然如果你去搜索一下也能得到答案,但是你知道这些答案背后的原理吗?
问题三
你的同学、同事在工作学习中可能不时就会提及到静态链接库动态链接库静态链接动态链接,每次听到这些词汇的时候在你脑海里,A)对此有很清晰的认知;B)一头雾水不知道他们在说些什么,你属于A还是B?
如果你还不能很好的解决上面前两个问题且对于问题三属于B,那么接下来你就要好好看这篇文章啦,解决这几个问题的关键就是这篇文章要介绍的链接器(Linker),虽然现代的集成开发环境IDE比如Visual Studio已经对程序员屏蔽了大部分链接器的工作,但理解链接器将极大提高你对工程的驾驭能力,也许你现在还不是很清楚,读完这篇文章你就能明白啦。
什么是链接器(Linker)
让我们引用维基百科中对链接器的定义:
a linker or link editor is a computer utility program that takes one or more object files generated by a compiler and combines them into a single executable file, library file, or another 'object' file.
如果你看不太懂没有关系,我来翻译一下,链接器是一个将编译器产生的目标文件打包成可执行文件或者库文件或者目标文件的程序。这个翻译比较拗口,不太好理解,这句话的意思具体如下:
首先是链接器的本质,链接器本质上也是一个程序,本质上和我们经常使用的普通程序没什么不同。
其次是链接器的输入,我们经常使用的程序比如播放器,其输入是一个MP4文件,而链接器的输入是编译器编译好的目标文件(object file,如果你不理解什么是目标文件,请参考之前的文章《不简单的hello world之C标准库》)。
最后是链接器的输出,链接器在将目标文件打包处理后,生成或者可执行文
件,或者库,或者目标文件。
从这个定义中能够看出,链接器的作用有点类似于我们经常使用的压缩软WinRAR(Linux下是tar),压缩软件将一堆文件打包压缩成一个压缩文件,而链接器和压缩软件的区别在于链接器是将多个目标文件打包成一个文件而不进行压缩。那么链接器到底是如何工作的呢,我们接着往下看。
《彻底理解链接器:二,符号决议》