1.编译过程
gcc 编译 c 代码
g++ 编译 c++ 代码
本文以g++为例。
首先,新建一个test.cpp文件:
touch test.cpp
写入简单程序
(备注:在终端中使用vim编译的时候,“set ts=4”命令可以修改tab为四个空格长度,使得界面更整洁)
编译过程有如下四个阶段
1.1 预处理
# -E 选项指示编译器 仅对输入文件进行预处理
# 将头文件,即所有包含的文件都放入同一个 *.i 文件
g++ -E test.cpp -o test.i
1.2 编译生成汇编文件
# -S选项告诉编译器,为C++文件生成汇编语言文件后停止编译
# 扩展名为 .s
g++ -S test.i -o test.s
# 或直接使用 g++ -S test.i
1.3 汇编
# -c 选项告诉编译器 把源码编译为机器语言
# 类似windows下的obj文件
# 扩展名.o
g++ -c test.s -o test.o
# 或直接使用 g++ -c test.s
1.4 链接成可执行文件
# 将静态库、动态库等连接成可执行文件
# -o 即指生成的文件,不加该选项,则默认生存a.out文件
g++ test.o -o test
以上过程可以一步完成,而这一步操作的执行过程,实际上就是以上四个步骤的依次执行。
g++ test.cpp -o test
执行效果:
2.重要编译参数
-o 指定输出文件名
-g 能产生供gdb使用的调试信息
-O[n] 对源代码进行优化
-O0 表示不做优化
-O1 表示默认优化
-O2 在O1的基础之上,还进行一些调整工作,如指令调整
-O3 包括循环展开和其他一些处理特性相关的优化工作
-l 和 -L (大小写 艾了)小写-l 用来指定要连接的库的库名, 大写-L
-I (大写的 艾)当头文件不在/usr/include下时,需要指明头文件路径
-Wall 打印警告信息
-w (小写)关闭警告信息
-std=c++11 设置编译标准
-D 宏定义,比如在代码中有“DEBUG”宏,那么编译时使用 -DDEBUG,即开启这个宏
2.1 -O2举例:
o2test.cpp代码如下
# include <iostream>
using namespace std;
int main()
{
unsigned long int counter;
unsigned long int result;
unsigned long int temp;
unsigned int five;
int i;
for(counter = 0; counter<(2021 * 2021 * 100 / 4 + 2021); counter +=((10 - 6) + (2 * 2))/8)
{
temp = counter / 1992;
for(i = 0; i< 29; i++)
{
five = 200 * 201 / 8000;
result = counter;
}
}
cout<<"result = "<<result<<endl;
return 0;
}
直接编译:
g++ o2test.cpp -o o2test_without_o
带O2优化的编译:
g++ o2test.cpp -O2 -o o2test_with_o2
可以对比一下编译生成的文件大小和执行速度:
2.2 -I举例(大写 艾)
示例代码准备如下:
d2.cpp文件和main.cpp都包含了d2.h头文件
编译时:
g++ main.cpp src/d2.cpp -I include/ -o console_add
结果:(不加 -I xxx,就会报错,显示没有该文件)
2.3 -Wall举例
使用上面的代码,对main.cpp作简单修改:
执行编译,不加-Wall和加上-Wall的效果如下:
3.动静态库的生存以及-l和-L的使用(大小写 艾了)
3.1 静态库
静态库本身是一种归档,
使用2.2中的代码
1、汇编,生成.o文件
# 先进入src目录
cd src
g++ d2.cpp -c -I ../include
2、生成静态库 .a文件,文件名必须是在原有名字前加上“lib”这样的形式
ar rs libd2.a d2.o
3、 连接静态库进行编译
# 先回到根目录
cd ..
g++ main.cpp -I include -l d2 -L src -o static_main
过程及结果如下:
3.2 动态库
1、生成动态库
依然使用上面的代码
# 进入src目录
cd src
# 删除d2.o,以防理解有误
rm d2.o
# 生成动态库
g++ d2.cpp -I ../include -fPIC -shared -o libd2.so
2、链接,编译,生成可执行文件
# 回到根目录
cd ..
#链接、编译
g++ main.cpp -I include -l d2 -L src -o dynamic_main
3、执行时可能会遇到无法加载动态库的错误
解决的方式有三种:1、把.so文件复制到系统默认检索路径下,2、给系统新增.so所在目录,3、把.so文件复制到执行文件所在目录