目录

一.背景知识

编译器的处理过程

二.gcc/g++的基本概念

GCC(GNU Compiler Collection)

gcc

g++

其他工具

三.gcc/g++的编译选项(以gcc为例)

验证gcc版本与安装

预处理

编译

汇编

链接

编译多文件项目

四.静态库与动态库

静态库(Static Library)

动态库(Dynamic Library)

如何更改gcc的链接方式

五.总结


一.背景知识

编译器的处理过程

1.预处理

  • 展开头文件
  • 去注释
  • 宏替换
  • 条件编译       

2.编译

  • C语言翻译为汇编语言

3.汇编

  • 汇编语言翻译成为二进制文件

4.链接

  • 将多个目标文件或库文件合并为最终可执行文件或共享库        

二.gcc/g++的基本概念

GCC(GNU Compiler Collection)

GCC 是由 GNU 项目开发的编译器套件,支持包括 C、C++、Fortran、Ada、Go 等多种编程语言。作为开源工具集,它具备跨平台能力,可在多种操作系统和架构上运行,是许多系统和开源项目的默认编译工具,在 GCC 中,gcc 和 g++ 分别是编译 C 和 C++ 代码的核心组件


gcc

  • 功能

    gcc 是 GCC 套件中用于编译 C 语言代码的编译器。它将 C 源代码编译为目标代码,并调用 GCC 后端生成可执行文件或库文件

  • 特点

    支持 ANSI C(C89/C90)、C99、C11 等 C 语言标准,可生成与目标平台兼容的高效可执行文件

  • 选项

    提供丰富的编译和优化选项,如优化级别控制(-O0/-O2)、调试信息生成(-g)、警告设置(-Wall)等


g++

  • 功能

    g++ 是 GCC 套件中专用于编译 C++ 代码的编译器前端,通过调用 GCC 后端生成目标代码

  • 特点

    全面支持 C++98、C++11、C++14、C++17 等标准,可编译符合不同规范的 C++ 代码并生成高效输出

  • 选项

    提供与 gcc 类似的编译控制选项,同时自动链接 C++ 标准库(如 libstdc++),支持异常处理、RTTI 等特性


其他工具

除编译器外,GCC 套件还包含:

  • 预处理器:处理宏定义和文件包含(cpp

  • 汇编器:将汇编代码转为机器码(as

  • 链接器:合并目标文件生成可执行程序(ld

这些工具共同完成从源码到可执行文件的完整编译流程


三.gcc/g++的编译选项(以gcc为例)

验证gcc版本与安装

gcc --version


格式:

gcc [选项] 要编译的⽂件 [选项] [⽬标⽂件]

预处理

gcc -E test.c -o test.i   # 预处理后形成一个.i文件

  • 预处理阶段
  • 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程
  • 选项“-o”,该选项的作用是形成一个指定名字的目标文件
  • “.i”文件为已经过预处理的C原始程序

编译

gcc -S test.i -o test.s

  • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言
  •  选项“-S” ,该选项的作用是只进行编译而不进行汇编,生成汇编代码


汇编

gcc -c test.s -o test.o

  • 汇编阶段是把编译阶段生成的“.s”文件转成“.o”目标文件
  • 选项“-c”,该选项的作用是将汇编语言翻译为可重定位二进制文件

可重定位二进制文件


链接

gcc test.o -o test   # 生成可执行文件或库文件

  • 在成功编译之后,就进入了链接阶段
  • 链接阶段,gcc将二进制文件与函数的实现所在库进行链接,从而生成可执行文件

上述的四个过程实则为中间过程,实际在运用时,可直接将源代码编译为可执行文件:

gcc test.c -o test   # gcc [目标文件] -o 要编译的文件
gcc -o test test.c   # gcc -o [目标文件] 要编译的文件

编译多文件项目

gcc 要编译的文件列表 -o 目标文件


四.静态库与动态库

静态库(Static Library)

  1. 链接过程
    静态库在编译链接阶段被直接整合到可执行文件中。链接器从库中提取被调用的函数/数据,将其机器码完整复制到最终二进制文件中

  2. 存储特性
    每个使用静态库的可执行文件都会包含该库的独立副本,导致可执行文件体积显著增大(库代码量×程序数量),因此可执行文件体积较大

  3. 运行时行为
    程序运行时无需外部库文件支持,所有依赖代码已硬编码在可执行文件中,实现完全自包含

  4. 文件规范

    • Unix/Linux系统:扩展名为 .a(如 libmath.a

    • Windows系统:扩展名为 .lib(如 openssl.lib


动态库(Dynamic Library)

  1. 链接过程
    动态库在编译阶段仅记录引用信息,实际链接推迟到程序运行时链接器在可执行文件中写入库的路径和符号表,不复制库代码

  2. 存储特性
    多个程序可共享同一动态库文件,磁盘和内存中只需存储一份副本,显著减少资源占用(100个程序共享1个 libz.so 仅需1份空间)

  3. 运行时行为
    程序启动时由动态加载器(Linux的ld.so/Windows的LoadLibrary)自动加载库到内存,若库缺失或版本不兼容会导致运行时错误(如 error while loading shared libraries

  4. 文件规范

    • Unix/Linux系统:扩展名为 .so(如 libc.so.6

    • Windows系统:扩展名为 .dll(如 kernel32.dll


如何更改gcc的链接方式

通过可执行文件的依赖库可以看到gcc的默认链接方式是链接动态库

若要让gcc的二进制程序进行静态链接,首先需要下载C/C++的静态库

sudo yum install -y glibc-static libstdc++-static

再在gcc的编译选项中选择静态链接(-static)

gcc main.c code.c -o code-static -static   #-static,此选项对生成的文件强制采用静态链接


五.总结

        本期介绍了 GNU 编译工具链的核心组件gcc和g++内容包括 GCC 工具集的整体认识、gcc与g++的具体区别、从源代码预处理、编译、汇编到链接的完整编译流程详解(包括多文件项目的处理)、以及静态库与动态库的原理、创建方法及其链接方式的选择与控制。这些知识为理解和掌握 C/C++ 程序的构建过程奠定了基础,下期我们将进一步探索项目构建自动化,详细介绍如何使用 make 工具和编写 Makefile 文件来高效地管理编译流程和项目构建任务

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐