gcc/g++

编译器 gcc/g++

背景知识

编译过程分为四个阶段:

阶段 说明
1. 预处理 进行宏替换、去注释、条件编译、头文件展开等
2. 编译 生成汇编代码
3. 汇编 生成机器可识别代码(目标文件)
4. 链接 生成可执行文件或库文件

gcc 编译选项

基本格式

bash 复制代码
gcc [选项] 要编译的文件 [选项] [目标文件]

预处理(进行宏替换)

  • 功能:宏定义、文件包含、条件编译、去注释等
  • 说明 :预处理指令是以 # 号开头的代码行
  • 选项-E(让 gcc 在预处理结束后停止编译过程)
  • 输出文件.i 文件(已经过预处理的 C 原始程序)

示例

bash 复制代码
gcc -E hello.c -o hello.i

编译(生成汇编)

  • 功能:检查代码规范性和语法错误,将代码翻译成汇编语言
  • 选项-S(只进行编译而不进行汇编,生成汇编代码)
  • 输出文件.s 文件(汇编代码)

示例

bash 复制代码
gcc -S hello.i -o hello.s

汇编(生成机器可识别代码)

  • 功能 :将 .s 汇编文件转成目标文件(二进制目标代码)
  • 选项-c
  • 输出文件.o 文件(目标文件)

示例

bash 复制代码
gcc -c hello.s -o hello.o

链接(生成可执行文件或库文件)

  • 功能:将目标文件链接成可执行程序
  • 说明:成功编译后进入链接阶段

示例

bash 复制代码
gcc hello.o -o hello

动态链接和静态链接

在实际开发中,多个源文件之间存在依赖关系。每个 .c 文件独立编译成 .o 文件,为了满足依赖关系,需要将这些目标文件进行链接,形成可执行程序。

静态链接

缺点

  • 浪费空间 :多个程序对同一个目标文件有依赖时,每个可执行程序都含有一份副本(如多个程序都调用 printf(),则每个程序都包含 printf.o
  • 更新困难:库函数代码修改后,需要重新编译链接形成可执行程序

优点

  • 可执行程序中已具备所有执行所需的内容
  • 运行时速度快

动态链接

动态链接把程序按模块拆分成相对独立的部分,在程序运行时才将它们链接在一起,而不是像静态链接那样把所有模块都链接成一个单独的可执行文件。

查看可执行程序依赖的动态库

bash 复制代码
$ ldd hello
linux-vdso.so.1 => (0x00007fffeb1ab000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff776af5000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff776ec3000)

ldd 命令用于打印程序或者库文件所依赖的共享库列表。

库的概念

C 程序中的 printf 函数并没有在代码中定义实现,stdio.h 中也只有声明。实际实现被放在 libc.so.6 库文件中

在没有特别指定时,gcc 会到系统默认搜索路径 /usr/lib 下进行查找,链接到 libc.so.6 库函数,从而实现 printf 函数------这就是链接的作用。


静态库和动态库

类型 说明 后缀名 链接时机
静态库 编译链接时,把库文件的代码全部加入到可执行文件中,运行时不再需要库文件 .a 编译时
动态库 编译链接时不加入代码,程序执行时由运行时链接文件加载库 .so 运行时

注意事项

  • gcc 在编译时默认使用动态库
  • 可以使用 file 命令验证生成的二进制程序是否为动态链接

示例

bash 复制代码
gcc hello.o -o hello   # 默认动态链接

gcc 其他常用选项(了解即可)

选项 说明
-E 只激活预处理,不生成文件,需要重定向到输出文件
-S 编译到汇编语言,不进行汇编和链接
-c 编译到目标代码(.o 文件)
-o 文件输出到指定文件
-static 对生成的文件采用静态链接
-g 生成调试信息,GNU 调试器(gdb)可利用该信息
-shared 尽量使用动态库,生成文件较小,但需要系统提供动态库
-O0 优化级别 0:不进行优化
-O1 优化级别 1:缺省值(默认级别)
-O2 优化级别 2
-O3 优化级别 3:优化级别最高
-w 不生成任何警告信息
-Wall 生成所有警告信息

说明-O0-O1-O2-O3 是编译器的优化选项的 4 个级别,-O0 表示没有优化,-O1 为缺省值,-O3 优化级别最高。

相关推荐
Championship.23.241 小时前
Linux 3.0 串口机制深度解析:传统8250驱动与基础RS-232/485支持
linux·运维·服务器
顾喵1 小时前
VME总线详解:原理、架构、时序、协议、迭代、调试与实战应用
linux·网络协议
AI行业学习2 小时前
CC‑Switch v3.16.1 免费下载(Windows+macOS+Linux)、使用方法【2026.6.11】
linux·开发语言·windows·python·macos·前端框架·html
睡一觉就好了。2 小时前
vim基础操作
linux·编辑器·vim
__Witheart__2 小时前
Ubuntu 根文件系统开发流程及注意事项
linux·ubuntu·rockchip
vortex52 小时前
解决 Alpine Linux 虚拟机从 VirtualBox 迁移到 VMware 的内核崩溃问题
linux·运维
qq_白羊座2 小时前
Linux 压缩 / 解压(tar)命令 + 参数详解
linux·运维·github
hj2862512 小时前
Rsync 数据同步 + Inotify 实时监控 完整版实操笔记3
linux·运维·网络
__Witheart__2 小时前
Linux SDK 中 build.sh 打包 updateimg 流程分析
linux·ubuntu·rockchip