ubuntu下用GNU(gcc/g++)进行编译

主要介绍在ubuntu下利用GNU进行编译的过程和部分指令的含义, 帮助新手小白入门。

(Part A.)写在前面的话

step1. 常说到的GNU、gcc和g++什么关系?

关于这个可能会困扰到你的问题,推荐gcc与g++的关系,博主给出了简短而详实的解释。

总结就是两句话:1. gcc是GNU的简称;2. g++包含gcc。

step2. 安装GNU的方案网上一大堆,这里也推荐一篇是我之前自己总结的ubuntu下CPP开发与GNU的安装

 

(Part B.) 下面介绍下在ubuntu下利用g++编译cpp文件

step1. 写一个简单的测试程序,当然要用到hello world啦!  命名为test.cpp

#include <iostream>

int main()
{
	std::cout << "Hello World!" << std::endl;

	return 1;
}

step2. 利用下述指令可以直接生成一个可执行文件

$ g++ test.cpp -o test

然后执行就可以看到打印结果啦

$ ./test
Hello World!

 

(Part C.)过程详解

上面Part B部分一行指令直接由.cpp源码文件生成了可执行文件(仅有文件名,没有扩展名)。这一过程主要包括四个阶段:预处理、编译、汇编、链接,下面分别对各个过程进行介绍。

step 0. 首先明确一下g++的命令格式

g++ [指令] 待处理文件 [指令] 输出文件

step 1. 预处理

预处理主要是针对文件中#include和宏指令进行处理的,处理的方式就是将这些指令对应的内容插入到其对应的地方。指令语句为:

$ g++ -E test.cpp -o test.i

其中,-E是指的调用预处理指令,用来处理test.cpp文件,处理的目的是生成一个.i的文件,我们用-o test.i来指明(对于cpp的预处理文件,也可以是.ii的后缀)。运行上述指令后,会在同级目录下生成test.i预处理文件。如下:

#include <iostream>
#define NUM 100

int main()
{
	std::cout << NUM << std::endl;	
	std::cout << "Hello World!" << std::endl;
	return 1;
}

上面一段代码是我们的实验代码,运行预处理指令后,会将#include和#define的内容插入到.i文件中,如下图所示:

宏指令NUM已经被100代替, 同时注意到main函数是从两万八千多行开始的, 之前的代码,其实就是#include的内容。

step 2. 编译

编译就是对预处理文件.i进行词法分析,语法分析,语义分析,最终产生汇编文件.s,可以简单理解为将C代码“翻译”成汇编代码。

$ g++ -S test.i -o test.s

 运行上述指令后,会在同级目录下生成test.s汇编文件。

step 3. 汇编

汇编是将汇编代码翻译成机器可执行的指令,生成目标文件.o。整个过程较为简单,几乎只是按照汇编指令和机器指令进行一一翻译。

$ g++ -c test.c -o test.o

运行上述指令后,会在同级目录下生成test.o目标文件。

step 4.链接

链接就是将全部的目标文件按照一定规则连接在一起,共同生成可执行文件的过程。

$ g++ test.o -o test

其中,链接指令是没有指令关键字的,所以g++后面直接键入需要连接的目标文件。之后会生成test可执行文件,一般可执行文件是没有后缀的。

step 5. 运行

运行可执行文件,即可得到预料的输出结果,如下所示。

$ ./test
100
Hello World!

 

(Part D. )总结

四个过程:预处理(.i文件) -> 编译(.s文件) -> 汇编(.o文件) -> 链接(可执行文件)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章