gcc编译
第1章 GCC编译器
GCC编译器: GCC(GNU Compiler Collection)是由 GNU 开发的编程语言编译器。 GCC最初代表“GNU C Compiler”,当时只支持C语言。 后来又扩展能够支持更多编程语言,包括 C++、Fortran 和 Java 等。 因此,GCC也被重新定义为“GNU Compiler Collection”,成为历史上最优秀的编译器, 其执行效率与一般的编译器相比平均效率要高 20%~30%。 GCC编译器。 linux系统天生带有gcc编译器。
MinGW MinGW是用于windows系统的编译器。
GCC编译工具链
GCC编译工具链(toolchain),是指以GCC编译器为核心的一整套工具。它主要包含以下三部分内容:
gcc-core:即GCC编译器,用于完成预处理和编译过程,把C代码转换成汇编代码。 Binutils :除GCC编译器外的一系列小工具包括了链接器ld,汇编器as、目标文件格式查看器readelf等。 glibc:包含了主要的 C语言标准函数库,C语言中常常使用的打印函数printf、malloc函数就在glibc 库中。 在很多场合下会直接用GCC编译器来指代整套GCC编译工具链。
g++编译器是用来编译cpp文件的。
编译的4个阶段
GCC 编译工具链在编译一个C源文件时需要经过以下 4 步:
预处理:为把头文件的代码、宏之类的内容转换成生成的.i文件,还是C代码。 编译:把预处理后的.i文件通过编译成.s文件,汇编语言。 汇编:将汇编语言文件生成目标文件.o文件,机器码。 链接:将每个源文件对应的.o文件链接起来,就生成一个可执行程序文件。
预处理阶段
新建一个简单的test.cpp文件
#include<iostream>
using namespace std;
int main()
{
cout<<"This is my first test file!"
return 0;
}
执行预编译命令:
- 预处理,可理解为把头文件的代码汇总成C代码,把*.c转换得到.i文件。
- -E 选项指示编译器只对输入文件进行预处理
g++ -E test.cpp -o test.i
生成test.i文件,使用vim打开如下
编译阶段
- -S 编译选项告诉g++在为c++代码产生了汇编语言文件后停止编译,会产生一个.s文件(汇编文件)
g++ -S test.i -o test.s
产生的文件内容如下:
汇编阶段
- -c 选项告诉g++把源代码编译为机器语言的目标代码
- 产生一个.o文件(目标文件)
g++ -c test.s -o test.o
链接阶段
- -o 选项指定了产生的可执行文件的文件名
g++ test.o -o test
执行./test命令:输出如下
This is my first test file!
在这里直接执行test命令的话,什么也不会发生,报错也不会!那么test的意义究竟是什么?
test
直接生成可执行文件
执行编译命令:会直接生成可执行文件test
g++ test.cpp -o test
执行./test命令——输出如下
This is my first test file!
综上可以发现:g++ test.cpp -o test 会直接生成可执行文件,而且不会产生中间文件。 这里做个实验:我们先移除其它文件,保留.cpp文件,直接使用g++不加参数生成test.i文件
g++ test.cpp -o test.i
然后执行./test.i文件会发现依旧会输出如下内容
This is my first test file!
所以我们可以发现,不加参数的情况下,不管-o后面的文件是什么后缀,产生的都是可执行文件。 再做一个实验:我们先移除其它文件,只保留.cpp文件,先生成.i文件,然后再执行g++命令。
g++ -E test.cpp -o test.i
g++ test.i -o test
我们会发现,在不加参数限制的情况下,g++命令都会直接生成可执行文件。
g++重要编译参数
-g参数
- -g 编译带调试信息的可执行文件
g++ -g test.cpp -o test
-O选项
- -O[n]表示优化等级:一般我们选择-O2
g++ -O2 test.cpp -o test
-l与-L指定库文件|库文件路径
- -l参数就是用来指定程序要链接的库,-l参数紧接着的就是库名。
- 在/lib和/usr/lib和/usr/local/lib里的库直接使用-l参数就能链接
//链接glog库
g++ -lglog test.cpp
- 如果库文件没有放在上面三个目录里,则需要使用-L参数来指定库文件所在目录
- -L参数后跟着的就是库文件的目录名
- 指定库文件目录后,需要再用-l参数指定库文件
g++ -L/home/omm/mytestlibfolder -lmytest test.cpp
-I指定头文件搜索目录
- /usr/include目录一般是不用指定的,gcc知道去那里找。但是如果头文件不在/usr/include里我们就要用-I参数来指定了。-I的是顺序可以任意放置,-I与头文件目录之间可以加空格或者不加空格。
g++ -I./myInclude test.cpp
-Wall 打印警告信息
- -Wall 打印警告信息
- 默认生成可执行的a.out文件
g++ -Wall test.cpp
-w 关闭警告信息
- -w 关闭警告信息
g++ -test.cpp
-std=c++11 设置编译标准
- -std=c++11 设置编译标准
-o 指定输出的文件名
- 如果不加上该参数就会默认生成a.out文件
g++ test.cpp -o test
-D 定义宏
在使用gcc/g++的时候定义宏。
第2章 GCC实战
新建swap.cpp文件
新建src文件夹,在该文件夹下存放swap.cpp文件
void swap(int& a,int& b)
{
int temp=a;
a=b;
b=temp;
}
新建swap.h文件
新建myInlucde文件夹,在该文件夹下存放swap.h文件
void swap(int& a,int& b);
新建main.cpp文件
#include<iostream>
#include"swap.h"
using namespace std;
int main()
{
int a=111;
int b=222;
cout<<"a="<<a<<" "<<"b="<<b<<endl;
cout<<"交换a和b"<<endl;
swap(a,b);
cout<<"a="<<a<<" "<<"b="<<b<<endl;
return 0;
}
执行编译
编译
g++ main.cpp ./src/swap.cpp -I myInlcude -o main
编译过后产生可执行文件main,执行该文件
./main
怎样通过设置环境变量的方式在其它目录下执行main程序呢?