• GCC 指令详解及动态库、静态库的使用


    🚀 优质资源分享 🚀

    学习路线指引(点击解锁) 知识定位 人群定位
    🧡 Python实战微信订餐小程序 🧡 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
    💛Python量化交易实战💛 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

    GCC 指令详解及动态库、静态库的使用

    一、GCC

    1.1 GCC 介绍

    GCC 是 Linux 下的编译工具集,是「GNU Compiler Collection」的缩写,包含 gcc、g++ 等编译器。这个工具集不仅包含编译器,还包含其他工具集,例如 ar、nm 等。

    GCC 工具集不仅能编译 C/C++ 语言,其他例如 Objective-C、Pascal、Fortran、Java、Ada 等语言均能进行编译。GCC 还可以根据不同的硬件平台进行编译,即能进行交叉编译,在 A 平台上编译 B 平台的程序,支持常见的 X86、ARM、PowerPC、mips 等,以及 Linux、Windows 等软件平台。

    1.2 安装 GCC

    首先,查看 gcc 是否安装:

    # 查看 gcc 版本
    $ gcc -v
    $ gcc --version
    
    # 查看 g++ 版本
    $ g++ -v
    $ g++ --version
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果在输入指令后可以获取到 gcc 版本,那么就表明你的 Linux 中已经安装了 gcc:

    如果没有安装,则可按照如下方法安装 gcc:

    # centos
    $ sudo yum update # 更新本地的软件下载列表, 得到最新的下载地址
    $ sudo yum install gcc g++ # 通过下载列表中提供的地址下载安装包, 并安装
    
    • 1
    • 2
    • 3

    1.3 GCC 工作流程

    1.3.1 一般使用流程

    首先准备一个 C 语言代码,并命名为 test.c:

    #include 
    #define MAX 3
    
    int main()
    {
        int i;
        for (i = 1; i <= MAX; i++) 
        {
            printf("Hello World\n"); // 输出 Hello World
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    一般情况下,我们可以直接通过 $ gcc test.c -o test编译 test.c,并通过$ ./test指令运行生成的可执行文件:

    • -o:output,是 gcc 编译器的可选参数,用于指定输出文件名及路径,默认输出到当前路径下。下图展示了如何通过 -o 参数修改输出路径:

    或者不使用 -o 参数,则生成一个默认名称的可执行文件 a.out:

    实际上,GCC 编译器在对程序进行编译的时候,分为了四个步骤:

    1. 预处理(Pre-Processing):

      • 在这个阶段主要做了三件事:展开头文件 、宏替换 、去掉注释行
      • 结果得到的还是一个 C 程序,通常是以 .i 作为文件扩展名
    2. 编译(Compiling) :

      • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码实际要做的工作
      • 在检查无误后,gcc 把代码编译成汇编代码,得到一个以 .s 作为文件拓展名的汇编文件。
    3. 汇编(Assembling):

    + 汇编阶段是把编译阶段生成的 .s 文件转化成目标文件
    + 最终得到一个以 .o 结尾的二进制文件
    
    • 1
    • 2
    1. 链接(Linking):这个阶段需要 GCC 调用链接器对程序需要调用的进行链接,最终得到一个可执行的二进制文件

    而 GCC 的编译器可以将这 4 个步骤合并成一个,这也就是为什么我们使用$ gcc test.c -o test就可以直接生成可执行文件 test 的原因。下面我们对这 4 个步骤做个详细的介绍。

    1.3.2 详细的工作流程
    1.3.2.1 预处理
    # 通过添加参数 -E 生成预处理后的 C 文件 test.i
    # 必须通过 -o 参数指定输出的文件名
    $ gcc -E test.c -o test.i
    
    • 1
    • 2
    • 3

    让我们来观察一下 test.i 中的代码内容(太长了,只观察 main 函数中的替换情况):

    int main()
    {
        int i;
        for (i = 1; i <= 3; i++)
        {
            printf("Hello World\n");
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    通过分析 test.i 可以发现:

    • 宏定义 MAX 被替换为了相应的值 3
    • 注释「// 输出 Hello World」也被去掉了
    1.3.2.2 编译
    # 通过添加参数 -S 将 test.i 转换为汇编文件 test.s(默认生成 .s 文件)
    $ gcc -S test.i
    $ gcc -S test.i -o test.s # 写法二
    
    • 1
    • 2
    • 3
    1.3.2.3 汇编
    # 通过汇编得到二进制文件 test.o(默认生成 .o 文件,object)
    $ gcc -c test.s
    $ gcc -c test.s -o test.o # 写法二
    
    • 1
    • 2
    • 3
    1.3.2.4 链接
    # 通过链接得到可执行文件 test
    $ gcc test.o -o test
    
    • 1
    • 2

    在成功生成 test.o 文件后,就进入了链接阶段。在这里涉及到一个重要的概念:函数库。

    在 test.c 的代码中,我们通过print()函数打印 Hello World 语句;但是在这段程序中并没有定义 printf 的函数实现,且在预编译中包含进去的「stdio.h」中也只有该函数的声明extern int printf (const char *__restrict __format,

  • 相关阅读:
    【FreeRTOS】14 Tickless低功耗模式
    力扣-58. 最后一个单词的长度
    网络编程入门
    数组模拟几种基本的数据结构
    如何靠掌握自己的大数据打破信息流的壁垒?
    【工作总结】证书到底有什么用?
    【VisDrone数据集】YOLOX训练VisDrone数据集步骤与结果
    进程间通讯-共享内存
    Blazor入门-连接MySQL的简单例子:列出数据+简单查询
    字符串输出记录(stringout/lso)
  • 原文地址:https://blog.csdn.net/qq_43479892/article/details/127594711