C/C++程序编译流程: 预处理->编译->汇编->链接
具体的就是:
源代码(source coprede)→预处理器(processor)→编译器(compiler)→汇编程序(assembler)→目标程序(object code)→链接器(Linker)→可执行程序(executables)
gcc常用选项:
选项 | 功能 |
---|---|
-v | 查看gcc 编译器的版本,显示gcc执行时的详细过程 |
-o | 指定输出文件名为file,这个名称不能跟源文件名同名 |
-E | 只预处理,不会编译、汇编、链接 |
-S | 只编译,不会汇编、链接 |
-c | 汇编,不链接 |
示例:main.c
;mymath.h
;mymath.c
// main.c
#include <stdio.h>
#include "mymath.h"// 自定义头文件
int main(){
int a = 2;
int b = 3;
int sum = add(a, b);
printf("a=%d, b=%d, a+b=%d\n", a, b, sum);
// mymath.h
#ifndef MYMATH_H
#define MYMATH_H
int add(int a, int b);
int sum(int a, int b);
#endif
// mymath.c
int add(int a, int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
一:预处理
预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。
1、把你所有引用的头文件打开来插入到我们本身的程序中。
2、预处理阶段会把我们程序中的所有宏进行替换掉,我们经常在程序开头定义一个宏定义,那宏定义的替换就是在预处理阶段完成的。
3、我们在编写程序的时候常常会写入一些注释,对程序并没有作用,所以在预处理阶段程序会把我们写入的编译删除掉,机器是看不到我们写的注释的。
4、我们的条件编译我们常常会写#ifdef这时候我们不符合条件的那一部分我们机器也是不会看到的,他不会进入到编译阶段。
gcc -E mymath.c -o mymath.i
gcc -E main.c -o main.i
二:编译
编译阶段主要完成的任务就是由编译器来检查一下你的程序是不是有问题是不是有一些语法错误,在IDE下编写程序的时候也会编译一下看看我们的程序有没有error或者warning再去执行。当你的程序没有问题的时候编译还会把c程序编程汇编语言。
gcc -S mymath.i -o mymath.s
gcc -S main.i -o main.s
三:汇编
汇编阶段就是把我们第二阶段生成的汇编代码变成我们的可执行文件,也就是把我们的汇编语言变成机器语言。
gcc -c mymath.s -o mymath.o
gcc -c main.s -o main.o
四:链接
链接截断实现某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数等等。所有的这些问题,都需要经链接程序的处理方能得以解决,执行链接后生成的是程序的执行文件。
gcc main.o -o main mymath.o
./main //执行
正常我们执行gcc main.c -o main mymath.c
会经过上述过程
file.i: 预处理 C 源代码后产生的中间文件(Intermediate file)
file.s: 汇编代码文件(Assembly file)
file.o:目标文件(Object file)