1.gcc编译器对程序的编译,分为四个阶段:
1>预编译(pre-processing):在预处理阶段,输入的是C语言的源文件,通常为*.c。它们一般带有*.h之类的头文件。这个阶段主要处理源文件中的#ifdef,#include,#define预处理命令。该阶段会生成一个中间文件*.i文件。
这个阶段使用命令:
gcc –E tiger.c –o tiger.i
它通过对源文件tiger.c使用-E选项来生成中间文件tiger.i
2>编译和优化(compiling):在编译阶段,输入的是中间文件*i,编译后生成汇编文件*.s
这个阶段使用命令:
gcc –S tiger.i –o tiger.s
3>汇编(assembing):在汇编阶段,将输入的汇编文件*.s转换成二进制机器代码*.o.
这个阶段使用命令:
gcc -c tiger.s –o tiger.o
4>链接(linking):最后在链接阶段将输入的二进制机器代码文件*.o,汇集成一个可执行的二进制代码文件。
这个阶段使用命令:
gcc tiger.o -otiger
注:
以上所有阶段,可以直接使用gcc -o tiger tiger.c,直接生成可执行文件。
gcc-o tiger tiger.c(也可以使用gcc tiger.c -o tiger)
2.在实际开发中,使用gcc编译源代码编译程序时,源文件通常不止一个,这时就需要使用gcc编译多个源文件。
使用下面的命令就OK:
gcc -otiger tiger1.c tiger2.c tiger3.c
该命令同时编译3个源文件tiger1.c,tiger2.c,tiger3.c最后生成一个可执行程序tiger(命令中不带用*.h文件)
注:一个程序无论是只有一个源文件还是有多个源文件,在所有被编译和链接的源文件中必须有且只有一个main函数,因为main()是每一个程序的人口点。
3.源文件,目标文件和可执行文件是编译过程中常用的名词
1>源文件通常指存放可以编辑代码的文件,如C文件后缀为.c,c++后缀为.cpp;
2>目标文件是指经过编译器的编译生成的CPU可识别的二进制代码,但是目标文件一般不能执行,因为其中的一些函数过程没有相关的指示和说明。
3>可执行文件是目标文件与相关的库链接后的文件,它是可以执行的。
4>预编译过程将程序中引用的头文件包含进源代码中,并对一些宏进行替换。
5>编译过程将用户可识别的语言翻译成一组处理器可识别的操作码,生成目标文件,通常翻译成汇编语言,而汇编语言与机器操作码之间是一种一对一的关系。
6>所有的目标文件必须用某种方式组合起来才能运行,这就是链接的作用。目标文件中通常仅解析了文件内部的变量和函数,对于引用的函数和变量还没有解析,这需要将其他已经编写好的目标文件引用进来将没有解析的变量和函数进行解析,通常引用的目标是库。链接完成后会生成可执行文件。
4.gcc的基本用法
gcc [options][filenames]
其中options就是编译器所需要的选项,filenames是相关的文件名。
1>-c:只编译,不链接成可执行文件,编译器是由输入的.c等为后缀的源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
2>-ooutput_filename:确定输出文件的名称output_filename,如果不用该选项,gcc就默认为源文件名.o文件。
3>-g:产生调试器gdb所必需的符号信息,要对源代码进行调试,就必须在编译程序时加入该选项。
4>-Wall:用来开启编译警告,利于程序捕捉错误。
5>-O :对程序进行优化编译,链接,采用这个选项,整个源代码会在编译,链接过程中进行处理,这样产生的可执行文件的执行效率较高,但是编译链接的速度就相对要慢一些。
6>-O2:比-O更好的优化编译,链接,但整个编译,链接过程会更慢。
注:
使用g++来编译C++程序,C++ 源程序后缀名为.cpp。
使用g++来编译C++程序,其后面参数的用法和gcc中的用法一样;
eg:
g++ -otiger tiger.cpp
执行完后,生成执行文件名为tiger的执行程序。
我们也可以使用gcc来编译c++程序,此时在编译程序时,要告诉系统使用C++标准库而不用c++标准库;因此在编译是要指定C++库。
eg:
gcc -o tiger tiger.cpp -lstdc++