第二个例子:如果模块中有x未被初始化,链接器会选择定义在另外一个模块中的强符号(这会导致许多不易察觉的错误)
会输出x=15212,规则2,函数f将很低调的将x改成15212,对main带来不易察觉的意外!特别是当重复定义的符号有不同的类型时,需要特别的谨慎。编译系统不会发出任何警告,而且会在程序执行很久以后才表现出来。使用GCC-fno-common可以告诉链接器,遇到这类情况,输入一条警告。
作者:进击吧巨人《深入理解计算机系统 》 | 链接
编译器编译后产生的目标文件是可重定位的程序模块,并不能直接运行,链接就是把目标文件和其他分别进行编译生成的程序模块(如果有的话)及系统提供的标准库函数连接在一起,生成可运行的可执行文件的过程。
重定位是链接器在完成符号解析后(知道了各个输入模块的代码段和数据段的大小)的一个步骤,其作用顾名思义就是重新定位,确定比如指令,全局变量等在运行时的存储器地址。 编译链接中的-可重定位目标文件
一篇2012年转的04年的文章,写得真好所以看得特别流畅
会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。 make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。