(GNUCompiler Collection,GNU编译器套件)是由GNU开发的编程语言译器。GNU编译器套件包括C、C++、Objective-C、Fortran、Java、Ada和Go语言前端,也包括了这些语言的库。(如libstdc++,libgcj等)
一、安装GCC
安装gcc/g++
# 安装软件必须要有管理员权限
# ubuntu
sudo apt-get update
sudo apt-get install gcc g++
gcc 安装完毕之后,可以查看版本:
# 查看 gcc 版本
$ gcc -v
$ gcc --version
# 查看 g++ 版本
$ g++ -v
$ g++ --version
二、gcc工作流程
gcc编译程序的过程:
gcc/g++ 在执行编译工作的时候,总共需要4步:
1、预处理,生成 .i 的文件[预处理器cpp]
这个阶段需要 GCC 调用预处理器来完成,最终得到的还是源文件,文本格式
2、将预处理后的文件转换成汇编语言, 生成文件 .s [编译器egcs]
这个阶段需要 GCC 调用编译器对文件进行编译,最终得到一个汇编文件
3、有汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]
这个阶段需要 GCC 调用汇编器对文件进行汇编,最终得到一个二进制文件
4、连接目标代码, 生成可执行程序 [链接器ld]
这个阶段需要 GCC 调用链接器对程序需要调用的库进行链接,最终得到一个可执行的二进制文件
链接分为两种,一种是静态链接,另外一种是动态链接。使用静态链接的好处是,依赖的动态链接库较少,对动态链接库的版本不会很敏感,具有较好的兼容性;缺点是生成的程序比较大。使用动态链接的好处是,生成的程序比较小,占用较少的内存。
举个例子:
// 假设程序对应的源文件名为 test.c
#include <stdio.h>
#include <math.h>
#define pi 3.1415926
float r,c,s;
int main()
{
printf("请输入圆的半径:");
scanf("%f",&r);
c=2*pi*r;
s=pi*r*r;
printf("圆的周长为:%.3f,圆的面积为:%.3f",c,s);
return 0;
}
第一步:对源文件进行预处理,需要使用的 gcc 参数为 -E
# 预处理, -o 指定生成的文件名
$ gcc -E test.c -o test.i
第二步:编译预处理之后的文件,需要使用的 gcc 参数为 -S
# 编译, 得到汇编文件
$ gcc -S test.i -o test.s
第三步:对得到的汇编文件进行汇编,需要使用的 gcc 参数为 -c
# 3汇编
$ gcc -c test.s -o test.o
第四步:将得到的二进制文件和标准库进制链接,得到可执行的二进制文件,不需要任何参数
# 链接
$ gcc test.o -o test
注意:在使用 gcc 编译程序的时候可以通过参数控制内部自动执行几个步骤
# 参数 -c 是进行文件的汇编, 汇编之前的两步会自动执行
$ gcc test.c -c -o Test.o
# 该命令是直接进行链接生成可执行程序, 链接之前的三步会自动执行
$ gcc test.c -o Test
三、gcc常用参数
选项 | 作用 |
-E | 预处理,生成.i文件 |
-S | 编译,生成.s汇编文件 |
-c | 汇编,编译源码生成.o目标文件 |
Null | 链接,并不需要任何选项 |
-o | 生成目标文件,如.i,.o,.s,可执行文件,默认为a.out文件等 |
-Wall | 使gcc对源代码有问题的地方发出警告 |
-I directory (大写的 i) | 指定 include 包含文件的搜索目录 |
-L | 指定编译的时候,搜索的库的路径。 |
-l | 在程序编译的时候,指定使用的库 |
-g | 在目标文件中嵌入调试信息,以便gdb调试程序调试 |
-O | 优化编译后的代码 |
-w | 不生成任何警告信息,不建议使用,有些时候警告就是错误 |
-D | 在程序编译的时候,指定一个宏 |
-fPIC/fpic | 生成与位置无关的代码 |
-shared | 生成共享目标文件,通常用在建立共享库时 |
四、gcc与g++的区别
1、对于不同后缀的文件当作程序不同。在代码编译阶段,c后缀的文件,gcc把它当做是C程序;g++当做是C++程序;对于.cpp后缀的文件,gcc和g++都会当做C++程序。
2、编译阶段调用不同,g++会调用gcc,对于 C++ 代码,两者是等价的,也就是说 gcc 和 g++ 都可以编译 C/C++ 代码
3、链接阶段方式不同,通常会用g++来完成,gcc 和 g++ 都可以自动链接到标准 C 库,g++ 可以自动链接到标准 C++ 库,gcc 如果要链接到标准 C++ 库需要加参数 -lstdc++,这是因为gcc命令不能自动和C++程序使用的库连接。