• 嵌入式Linux应用开发基础知识——GCC编译过程


    目前很多IDE(集成开发环境)把编译过程封装的很好,导致很多嵌入式软件工程师不知道一个C程序的具体的编译过程,这一章我们来讲讲C程序的编译过程。

    1. GCC编译过程(精简版)

    如下图所示,一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)和链接(linking)等4步才能变成可执行文件。在日常交流中通常使用“编译”统称这4个步骤.
    在这里插入图片描述
    通过不同的gcc选项可以控制这些过程:
    在这里插入图片描述
    在日常交流中通常使用“编译”统称这4个步骤,如果不是特指这4个步骤中的某一个,本教程也依惯例使用“编译”这个统称。
    gcc使用示例:

    gcc hello.c                   // 输出一个名为a.out的可执行程序,然后可以执行./a.out
    gcc -o hello hello.c          // 输出名为hello的可执行程序,然后可以执行./hello
    gcc -o hello hello.c -static  // 静态链接
    gcc -c -o hello.o hello.c  // 先编译(不链接)
    gcc -o hello hello.o       // 再链接
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 预处理

    2.1 预处理含义

    故名思意就是预先处理,其中处理了以下几部分:

    • 展开包含的头文件,即#include后包含的头文件,全部复制到当前程序展开。
    • #define定义的符号替换
    • 进行条件编译
    • 删除所有注释

    2.2 预处理实验

    使用GCC编译器,可以通过加上-E选项指定只进行预处理过程。如

    gcc -E -o hello.i hello.c
    
    • 1

    -o 选项表示指定输出文件,上述语句表示将hello.c文件只进行预处理,生成hello.i文件(.i后缀为预处理过后的文件格式)
    下图左边为.C文件,右边为.i部分文件,可见首先将头文件stdio.h进行展开,由于stdio.h包含了其他文件,所以该展开会进行递归,将所有涉及的文件都展开。
    在这里插入图片描述
    如下图所示,预处理后的文件将宏定义的MAX和MIN进行了替换
    在这里插入图片描述如下图所示,预处理还会进行条件编译,如果条件为假,那么用空行替换相应的语句
    在这里插入图片描述

    下图注意到注释使用了空行进行替换(一行注释使用空行,如果是部分注释则使用空格进行替换)
    在这里插入图片描述

    2. 编译

    2.1 含义

    编译过程是将源文件编译为将C语言代码转换成汇编代码,还有一些更复杂的操作。

    2.2 实验

    使用GCC编译器,可以通过加上-E选项指定只进行预处理过程。如

    gcc -S -o hello.s hello.i
    
    • 1

    生成的汇编文件如下图所示
    在这里插入图片描述

    3. 汇编

    3.1 含义

    主要将汇编代码转换成二进制指令(机器指令)

    3.2 实验

    使用GCC编译器,可以通过加上-c选项指定只进行预处理过程。如

    gcc -c -o hello.o hello.s
    
    • 1

    生成的二进制文件如下图所示(使用文本编辑器打开会出现乱码)
    在这里插入图片描述

    4. 链接

    4.1 含义

    将所有的二进制文件(.o文件)进行链接,生成可执行文件.elf

  • 相关阅读:
    敬请期待!
    JAVA全局异常处理
    网络通信设备之网络路由技术详解
    【QT】信号和槽
    macOS Ventura 正式版你确定不更新,好用到爆的功能你不想尝试一下?
    PS太难学,这款软件更简单!——Lightroom
    通过L-evy飞行进行布谷鸟搜索
    Golang开发-new关键字
    Revit建模如何一键“生成场地和基础垫层”
    UI 自动化测试框架:PO模式+数据驱动
  • 原文地址:https://blog.csdn.net/FourLeafCloverLLLS/article/details/126166832