1. C语言从代码变成可执行程序的步骤:
预处理 -----> 编译 -----> 汇编 -----> 链接
1.1 预处理
- 作用:去掉注释,加载头文件,代替宏定义,条件编译
- 需要文件:.c文件
- 生成产物:预处理文件(以.i结尾)
- 使用方法:gcc hello.c -E -o hello.i
1.2编译
- 作用:使用编译器进行C语言的语法检查,如果有语法错误,报错,并结束编译过程;如果没有语法错误,把C的源程序转变为汇编代码
- 需要文件:.i文件
- 生成产物:汇编文件(以.s结尾)
- 使用方法:gcc hello.i -S -o hello.s
1.3 汇编
- 作用:把汇编源文件通过汇编器生成目标文件(二进制机器语言)
- 需要文件:.s文件
- 生成产物:机器码(或称为“目标代码”,以.o结尾)
- 使用方法:gcc hello.s -c -o hello.o
1.4链接
- 作用:把目标文件执行所依赖的所有二进制的其他目标文件及C的库文件都整合成一个可执行文件的过程
- 需要文件:.o文件及各种动态库或静态库
- 生成产物:可执行程序
- 使用方法:gcc hello.o -o hello
2.什么是gcc / g++
首先说明:gcc 和 GCC 是两个不同的东西
- GCC:GNU Compiler Collection(GUN
编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。 - gcc是GCC中的GUN C Compiler(C 编译器)
- g++是GCC中的GUN C++ Compiler(C++编译器)
一个有趣的事实就是,就本质而言,gcc和g++并不是编译器,也不是编译器的集合,它们只是一种驱动器,根据参数中要编译的文件的类型,调用对应的GUN编译器而已,比如,用gcc编译一个c文件的话,会有以下几个步骤:
- Step1:Call a preprocessor, like cpp.
- Step2:Call an actual compiler, like cc or cc1.
- Step3:Call an assembler, like as.
- Step4:Call a linker, like ld
由于编译器是可以更换的,所以gcc不仅仅可以编译C文件。所以,更准确的说法是:gcc调用了C compiler,而g++调用了C++ compiler
3. gcc和g++的主要区别
-
对于 .c和.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)
-
对于 .c和.cpp文件,g++则统一当做cpp文件编译
-
使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL
-
gcc在编译C文件时,可使用的预定义宏是比较少的
-
gcc在编译cpp文件时/g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏,这些宏如下:
#define __GXX_WEAK__ 1
#define __cplusplus 1
#define __DEPRECATED 1
#define __GNUG__ 4
#define __EXCEPTIONS 1
#define __private_extern__ extern
- 在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个
4. 主要参数
- -O0: 不进行代码优化。
- -O1 :1级代码优化。
- -O2 :2级代码优化。
- -O3 :3级代码优化。
- -o :生成指定的输出文件。用在生成可执行文件时。
- -g: 生成调试信息。GNU 调试器可利用该信息。
- -c: 只编译并生成目标文件。
- -shared: 生成共享目标文件。通常用在建立共享库时。
- -static: 禁止使用共享连接。
- -w: 不生成任何警告信息。
- -Wall: 生成所有警告信息。
- -lLIBRARY 连接时搜索指定的函数库LIBRARY。
- -IDIRECTORY 指定额外的头文件搜索路径DIRECTORY。
- -LDIRECTORY 指定额外的函数库搜索路径DIRECTORY。