一文弄懂c/c++编译过程(预处理,编译,汇编,链接)

1. 为什么要编译

  c语言是一门高级语言,需要编译器将其转换成计算机能理解的机器语言,才能在计算机上执行。编译的过程就是将c语言代码转换成汇编代码文件的过程。

2. 编译过程

  程序从代码编译成可执行文件或者库需要经历预处理,编译,汇编和链接四个阶段.这四个阶段如同工厂流线一样对代码进行一道有一道无情的加工.如下图:

请添加图片描述

  2.1. 预处理:

  预处理主要将代码中的注释删除。替换使用#defined指令的常量值和表达式的宏定义。将#include指令包含的文件中的内容添加到当前文件中,最终生成.i文件。

   gcc -E main.c -o main.i
   -E 让gcc在预处理结束后停止编译
   -o 执行目标文件
   .i文件是完成预处理过程的c语言原始文件

  2.2. 编译

  将源码转换成机器语言。这一步将.i临时文件转换为具有汇编级指令的汇编文件.s文件。

  注意此步依然是代码,只不过转换成汇编代码。因为涉及c语言转换成汇编语言,所以该步可以检测出源代码终存在的语言错误或警告。

   gcc -S main.i -o main.s
   -S 让gcc只编译不进行汇编
   .s 汇编文件

  2.3. 汇编

  将汇编程序代码.s文件转换成机器可理解的代码。对应的文件扩展名为.o

  这一步生成的的机器代码,是计算机可理解的代码。由于此步骤生成的机器代码相互独立,而一个程序中由多个机器代码相互依赖,所以该步骤程序依然不能独立运行,需要经过下一步链接。

   gcc -c main.s -o main.o

  2.4. 链接

  将汇编的二进制目标代码链接起来,生成可执行文件或库文件,也会自动链接系统库函数,如printf函数,在stdio.h中定义,但是在libc.so.6中实现,会链接该库.

   gcc -o main main.o

3. 实验验证

  3.1 首先建立三个文件hello.c hello.h main.c分别写入如下内容

 /// hello.h
 #pragma once
 
 #define NAME  "xiangli"
 const ConstValue = 123;
 void func();
 
 
 /// hello.c
 void func(){
    
    
 	return;
 }
 
 
 /// main.c
 #include "hello.h"
 #include "stdio.h"
 int main(int argc, const char** argv) {
    
    
     printf("hello world  %s", NAME);
     func();
     return 0;
 }

  3.2 验证预处理过程:

  查看头文件是否包含,宏定义是否替换

 ```makefile
 # 执行
 gcc -E main.c -o main.i
 gcc -E hello.c -o hello.i

  执行上面两条命令,如下图,可以看见文件夹中生成了两个新文件hello.imain.i。其中main.i内容比main.c文件多了很多内容,也包含了hello.h中的内容。这就是预处理将include文件添加到当前当前文件中。

请添加图片描述

  3.3 验证编译过程:

  查看编译后生成的汇编代码

# 执行
gcc -S main.i -o main.s
gcc -S hello.i -o hello.s

  执行完上面两条命令,文件夹中新增了两个.s后缀的文件 ,这便是汇编代码的程序。这一步会对代码语法进行检查并进行提示错误或告警。
  小插曲:上述代码hello.h文件中常量没有指定类型const ConstValue = 123;,定义错误在此步骤进行了告警提示。改正后,继续进行下面实验。

请添加图片描述

  3.4 验证汇编过程:

# 执行
gcc -c main.s -o main.o
gcc -c hello.s -o hello.o

  执行完上面代码,生成两个.o文件。该文件便是执行汇编后生成的二进制文件。

  3.5 验证链接过程:

# 执行
gcc -o main main.o hello.o

  执行完上面代码,文件夹中生成main.exe文件,该文件是链接汇编中两个.o文件和库文件生成的可执行文件。可在计算机中直接运行。

请添加图片描述

  至此,c/c++程序编译部分写完了,由于能力有限,肯定存在错误和不足,欢迎留言指正。后面我将会介绍make, cmake,gcc,gdb等编译调试工具在程序编译中的作用,以及vscode如何编译调试c/c++程序,欢迎关注。

猜你喜欢

转载自blog.csdn.net/qq_41546984/article/details/131364400