"木叶飞舞之处"
一, gcc编译器
- GCC编译器支持编译GO, Objective-C, Objuctive-C++,D等程序;
- Linux开发C/C++一定要熟悉GCC
- VSCode是通过调用GCC编译器来实现C/C++的编译工作的;
- 实际使用中:
- 使用gcc指令编译C代码
- 使用g++指令编译C++代码
二, gcc的编译过程
1–完整版
为了便于理解一个gcc的编译过程,将完整的代码编译过程分为以下四步(现在已经简化为一句代码就可实现这几句话),以一个test.cpp文件编译成可执行文件为例:
1. 预处理
预处理-Pre-processing: 生成.i文件
# -E 选项 代表指示编译器仅对输入文件进行预处理
g++ -E test.cpp -o test.i
2. 编译
编译-Compiling: 生成.s文件
# -S 告诉C++代码产生汇编语言
# g++ 产生的汇编语言文件缺省扩展名是 _s
g++ -S test.i -o test.s
3. 汇编
汇编-Assembling: 生成.o文件
# -c 告诉C++代码产生机器语言
# g++ 产生的机器语言的缺省扩展名是.o
g++ -c test.s -o test.o
4. 链接:
链接-Linking: 生成.bin文件
# -o 表示为可执行文件重新命名,之前的-o都是
g++ test.o -o test
2–简化版
简化编译过程
一步代码融合了上述四个步骤:
如果没有-o参数,会默认生成a.out可执行文件
g++ test.cpp -o test
3–编译完成
同级目录下出现了test可执行文件,运行:
./test
即可执行
三, g++重要编译参数
1. 使能gdb调试
- -g选项允许gcc产生带调试信息的可执行文件test
g++ -g test.cpp -o test
2. 优化代码
- -O[n]中,一般选择-O2, n的取值如下:
- -O:同时减小代码长度和执行时间,其效果等价于-O1
- -O0: 表示不做优化
- -O1为默认优化
- -O2:在-O1基础上,进行一些额外调整,如指令调整
- -O3:包含循环展开和其他优化工作
# 这样出来的程序,运行时间和文件大小都优化了,time ./test指令可以查看运行时间
g++ -O2 test.cpp -o test
3. 指定库路径-l和-L
- -l参数(小写)就是用来制定程序要链接的库,-l后接库名,没有空格
- 在/lib /usr/lib /usr/local/lib 里的库直接用-l就可以链接
g++ -lglog test.cpp -o test
- -L参数可以制定库文件没在上述三个目录中的库文件,后接库名无空格
g++ -L/home/home/qinsir/mylib -lmytest test.cpp -o test
4. 指定头文件搜索目录-I
- /usr/include目录一般不用指定
- 不在上述目录的,需要用-I(大写)参数指定
- -I可以用相对路径,不如头文件在当前,就可以用-I.来指定
g++ -I/. test.cpp -o test
5. -Wall 打印警告
- 打印出gcc提供的警告信息
g++ -Wall test.cpp -o test
6. -w 关闭警告
用法同上
7. -std=c++11 设置编译标准
- 使用c++11标准编译test.cpp
g++ -std=c++11 test.cpp -o test
8. 定义宏
- -DDEBUG定义DEBUG宏,可能文件中含有DEBUG宏部分的相关信息,用DDEBUG来选择开启或关闭DEBUG
- -Dname定义宏name,默认定义内容为字符串1
- 博主自己认为可以用来作为负责开关的调试变量
gcc -DDEBUG main.cpp -o test
main.cpp文件内容:
int main()
{
#ifdef DEBUG
printf("DEBUG LOG\n");
#endif
printf("in\n") ;
}
按照上述编译,DEBUG为真,输出"DEBUG LOG"