LINUX--编译器gcc/g++
目录
背景知识
gcc和g++的区别
程序的翻译过程以及gcc命令
动态链接和静态链接
静态链接
动态链接
静态库和动态库
背景知识
gcc和g++的区别
- gcc:C语言编译器,只能用来编译C语言。
- g++:是一个C/C++语言编译器
虽然g++既可以编译C语言又可以编译C++,我们还是建议C语言用gcc编译,C++用g++编译。这样可以确保语言语法解析的准确性。
程序的翻译过程以及gcc命令
- 预处理(code.i)
进行头文件的展开,去注释,宏替换以及条件编译等工作。
- 编译(code.s)
程序开始翻译,从C语言翻译成汇编语言。
- 汇编(code.o)
把汇编语言翻译成二进制。
.o是可重定位目标目标二进制文件,现在还是无法运行的,因为没有链接的话,我们用到的库方法只有声明,没有定义。
- 链接
生成可执行性文件或者库文件。
上面的四个过程实际是中间过程,在实际运用中,我们可以直接将源代码编译为可执行文件:
如果我们要执行文件,用:
动态链接和静态链接
静态链接
在我们的实际开发中,不可能将所有代码放在⼀个源⽂件中,所以会出现多个源⽂件,⽽且多个源。⽂件之间不是独立的,⽽会存在多种依赖关系,如⼀个源⽂件可能要调⽤另⼀个源文件中定义的函数, 但是每个源⽂件都是独⽴编译的,即每个*.c⽂件会形成⼀个*.o⽂件,为了满⾜前⾯说的依赖关系,则需要将这些源⽂件产⽣的⽬标⽂件进⾏链接,从⽽形成⼀个可以执⾏的程序。这个链接的过程就是静态链接。
静态链接的缺点:
-
浪费空间:因为每个可执⾏程序中对所有需要的⽬标⽂件都要有⼀份副本,所以如果多个程序对 同⼀个⽬标⽂件都有依赖,如多个程序中都调⽤了printf()函数,则这多个程序中都含有printf.o,所以同⼀个目标⽂件在内存存在多个副本。
-
更新比较困难:因为每当库函数的代码修改了,这个时候就需要重新进⾏编译链接形成可执⾏程序。
静态链接的优点:
在可执⾏程序中已经具备了所有执⾏程序所需要的任何东西,执行的时候运⾏速度快。
动态链接
动态链接的基本思想是把程序按照模块拆分成各个相对独⽴部分,在程序运⾏时才将它们链接在⼀起形成⼀个完整的程序,⽽不是像静态链接⼀样把所有程序模块都链接成⼀个单独的可执⾏⽂件。我们查看一下这个file可执行程序所依赖的动态库,发现它用到了一个C动态链接库:
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?
答案是: 系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。
静态库和动态库
- Linux下,动态库xxx.so, 静态库xxx.a
- Windows下,动态库xxx.dll, 静态库xxx.lib