Linux系统下开发c++程序,那么gcc编译器就是我们绕不过去的一道坎。gcc是GNU出品的一款可以在多种硬件平台上编译处可执行程序的超级编译器,其执行效率比普通的编译器要高出20%~30%左右,而且它是开源,因此很多著名的软件都能通过它进行编译。
对于我们来说,有时候尽管写着linux c++的代码,但是很多时候我们不会去深究其中的深层次东西。向我这样拥有着最低追求的程序员,能够写出符合要求的代码可能就算完事了。不过呢,多知道一些东西总归是有好处的。知道其原理,我们才能更好的写出高质量的代码,更好的提高我们的工作效率。
gcc编译C/C++的编译过程可以分为4个阶段:
1.预处理(Preprocess:生成 .i 的文件
2. 编译(Compilation):将预处理后的文件不转换成汇编语言, 生成文件 .s
3. 汇编 (Assembly:由汇编变为目标代码(机器代码)生成 .o 的文件
4. 链接(Linking):连接目标代码, 生成可执行程序
复制代码
预处理
预处理其实就是对程序中的伪指令(#开头的指令)和特殊符号进行处理的过程。 其中伪指令包括宏定义指令、条件编译指令以及头文件包含指令。
预编译过程中的主要处理规则如下:
1.删除#define定义,并且展开所有的宏定义
2.处理所有的条件编译指令,如#ifdef...
3.处理#include指令 ,将被包含文件插入到指令位置,实质上和宏定义一样,只不过这里是展开文件内容
4. 删除源代码中的注释
5. 添加行号以及标识
复制代码
那么,我们还是以HelloWorld程序作为我们的示例程序吧。
这里我么就不用集成IDE了,我们直ssh到我们的linux机器。
首先我们找一个目录,然后编写一个helloWorld程序:
//编辑代码
vi hello.c
// 查看文件内容
ls
hello.c
// -n 参数可以显示行号
cat -n hello.c
1 #include <stdio.h>
2
3 //函数入口
4 int main(int argc, char *argv[])
5 {
6 // 打印欢迎语句
7 char hello[] = "Hello,Linux C++!";
8 printf("%s",hello);
9 return 0;
10 }
复制代码
接下来我们执行gcc的预处理命令:
gcc -E hello.c -o hello.i
复制代码
可以看到目录下会生成hello.i 文件:
我们可以查看一下hello.i的内容:
编译
编译过程就是把预处理完成的文件进行一系列的词法分析,语法分析。。。然后生成对应的汇编文件。默认情况gcc不会生成后缀为.s的汇编文件,如果需要我们需要使用-S选项。
语法:
gcc -S hello.i -o hello.s
复制代码
生成的汇编文件代码,这里我贴出来,说实话看不太懂。。。
汇编
汇编就是将汇编代码转化为机器可以执行的二进制代码。
语法:
gcc -S hello.s -o hello.o
复制代码
至于查看hello.o可以使用下面的命令:
hexdump hello.o
复制代码
链接
这个阶段主要是为了解决多个文件之间的符号引用的问题。 就拿hello.c来说,我们在程序中使用了printf函数,但是我们并没有其声明和实现。可能有朋友会说,我们不是引用了stdio.h吗?是的,我们确实在我们的文件中引用了头文件,可问题是头文件中也只会有printf的声明,而在实际的运行中,我们需要函数的实现。所以我们可以将链接这个过程描述为:我知道你是谁,但我们要明确你在哪里?
gcc会在系统默认的搜索路径:/user/lib64 下去查找。
语法:
gcc hello.o -o hello
复制代码
最后运行:
./hello
复制代码