本文经验大部分来自ds,小部分来自自己的想法。欢迎各位大佬rape me。
只针对c/c++语言编译器的编译安装。
本文适用于Ubuntu系统,其他系统请靠AI举一反三。
不想看废话,直接冲标题五!!!
一、为什么要编译安装GCC
平常linux,如Ubuntu的官方GCC(不是c编译器,是GCC项目)版本过低,自己想捣鼓高版本的GCC(不是c编译器,是GCC项目)因此就需要编译安装高版本的GCC(不是c编译器,是GCC项目),举个极端的例子,你不能指望Ubuntu22.04的官方GCC(不是c编译器,是GCC项目)可以写C23,C++26吧?
二、事前准备
1.安装编译工具包
必须先有鸡才有蛋,当然第一只鸡🐔当然是纸条带的机器指令啦~~
工具包括gcc(c编译器),g++,make,libc6-dev(C 标准库和头文件),dpkg-dev(将编译好的软件整理成安装包)等。
还有GMP,MPFR,MPC库,如果没有,也自行从官方库下载,或者自己动手编译安装一个。
以及GCC(不是c编译器,是GCC项目)源代码,这个去镜像源拿一个,哪个版本随你挑选,建议拿比系统版本高的版本。
贴一个16.2版本的GCC(嘻嘻-2026.9.23):
wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-16.2.0/gcc-16.2.0.tar.xz
2.安装Python3
用来跑编译脚本的,小弟我也看不懂这种脚本。。。
3.其他库
包括数学库,二进制工具,C++标准库开发,运行时库,安全加密库,压缩库,终端界面库,可选的高级库等,这些不用管,瞎安装就是了。
3.综合
libstdc++-dev在ubuntu22中有好几个版本,我选择了libstdc++-12-dev。(2026.9.23)
sudo apt update sudo apt install build-essential python3 libc6-dev binutils \ libgmp-dev libmpfr-dev libmpc-dev \ libstdc++-12-dev libgcc-s1 \ zlib1g-dev libssl-dev libncurses5-dev pkg-config或者,跑去你下载的GCC目录下执行(安全靠谱,但是可能速度贼慢,因为防火墙;大佬可以自己改这个文件或者魔法吧):
./contrib/download_prerequisites三、编译环节
1.GCC包括什么语言
| 语言 | 参数值 | 状态 |
|---|---|---|
| C | c | 核心支持 |
| C++ | c++ | 核心支持 |
| Objective-C | objc | 支持 |
| Objective-C++ | obj-c++ | 支持 |
| Fortran | fortran | 支持 |
| Go | go | 支持 |
| D | d | 支持 |
| Ada | ada | 支持 |
| Modula-2 | m2 | 支持 |
| Rust | rust | GCC 16 新增 |
| COBOL | cobol | GCC 16 新增 |
Java (gcj) | - | GCC 7 已移除 |
| Python | - | 不支持(但编译依赖 Python 3) |
2.configure指令
configure是自动化生成make文件的,需要输入相应的参数才能生成相应的make文件,make文件决定你怎么编译GCC,把GCC放在哪里。
首先,指定只编译c和c++编译器,其他编译器用不上;
--enable-languages=c,c++
如果想当M,可以启动编译所有语言处理器,不过是另外的话题了,毕竟其他语言处理器也需要先有鸡🐔,再有蛋
--enable-languages=all
然后,指定编译后文件放在哪里,一般放在/usr/local那里,建议先实现创建好该文件夹;
--prefix=/usr/local/gcc2
再者,是否使用系统官方自带zlib库;
--with-system-zlib
接着,是否启用并行链接器(c,c++编译过程分预处理,编译,汇编和链接四个步骤,这四者皆可并行执行),有些GCC没有ld.gold链接器,因此此项不能用,需要自己看看。当然,现代链接器已经够用,不需要这项。
先说ld.gold的缺点:二进制体积大;优点:链接时快一点点。然后,据说gnu社区已经把它弃用了(悲~)。(2026.9.23)
| 参数 | 作用 |
|---|---|
-fuse-ld=gold | 核心开关:强制 GCC 调用ld.gold |
-flto=auto | 开启 LTO,auto模式自动使用多线程 |
LDFLAGS="-flto=auto -fuse-ld=gold"
最后,优化
--enable-lto | 启用链接时优化框架支持 |
| --disable-multilib | 取消32位GCC的支持,懒得支持了(2026.9.23) |
查看帮助
./configure --help
综合
./configure \ --prefix=/usr/local/gcc2 \ --enable-languages=c,c++ \ --enable-lto \ --disable-multilib
3.在源代码文件夹里面创建build文件夹
mkdir build && cd build
然后
../configure \
--prefix=/usr/local/gcc2 \
--enable-languages=c,c++ \
--enable-lto \
--disable-multilib
这样,所有杂七杂八的东西就会生成在build文件夹里面了,而不是跟源代码杂居。。。
4.启用make编译!!
make -j$(nproc)
这个会自动识别你电脑最大的CPU核心数,然后全员动员并行编译!!!
或者使用ninja(优势在于增量编译,初次编译差别不大)
make ninja -j$(nproc)
编译好后,
sudo make install
就可以在/usr/local/gcc2看见所有GCC程序啦。
5.!!!添加系统变量!!!(关键)
个人建议添加gcc,g++等编译器所在的文件夹目录以及他们的头文件所在的文件夹目录即可。
添加环境变量这个东西,相信各位大佬都是会的。
当然,与原有GCC(是GCC项目,不是编译器)发生冲突咋办?
a.改名(有点抽象的做法)
b.软连接(相信各位冠希哥也会,小弟我不献丑了)
c.将自己编译的GCC环境变量优先于系统GCC(小弟我选择的方案)
6.验证
gcc --version
四、其他
1.在Windows上使用mingw-w64
一般使用预编译好的文件就可以直接使用Windows版本的GCC了,不需要编译安装,在这个操作系统编译安装属于小众行为。
2.交叉编译GCC
只需要改变编译器后端选项就可交叉编译,比如你在x86架构上交叉编译出生成arm架构代码的GCC,这个GCC可以跑在x86架构上,但是却生成arm架构的可执行程序。
3.分布式编译安装
使用distcc。
你可能会想,使用物理机的多个虚拟机分布式编译安装是否可行?
答案是不如一个物理机的一个虚拟机编译安装(比如wsl2,vmware等),或者物理机自己就是Linux,使用物理机自己就行。具体原理,小弟我不知道,但是男人的第六感,你懂的。
4.mingw-w64跟GCC的差异
a. Linux 与 Windows 的差异
| 系统 | 异常模型 | 特点 |
|---|---|---|
| Linux | DWARF(统一) | 零运行时开销,依赖系统运行时库 |
| Windows | DWARF-2 / SJLJ / SEH(可选) | 多种模型可选,由 MinGW-w64 提供 |
b. Windows 上三种模型对比
| 模型 | 工作原理 | 优点 | 缺点 |
|---|---|---|---|
| DWARF-2 (DW2) | 使用 DWARF 格式的栈展开信息 | 零运行时开销,性能好 | 不支持 Windows SEH,无法捕获硬件异常 |
| SJLJ | 通过setjmp/longjmp模拟异常 | 跨平台性好,任何环境都能工作 | 运行时开销大,每次进入try块都有成本 |
| SEH | 直接使用 Windows 原生异常机制 | 与 Windows 深度集成,能捕获硬件异常 | 性能稍差 |
为什么会这样?
Linux 内核和 C++ 运行时完全信赖 DWARF 标准
Windows 内核有自己原生的 SEH 机制,GCC 作为"外来者",提供多种方式来适配或绕过这种差异
MinGW-w64 默认使用 DWARF-2,但对 SEH 的支持也越来越完善
5.为什么编译GCC时shell会出现警告
不用管,大概率是你的环境跟开发GCC的大佬的环境不一样,或者编译器版本问题
6.硬件加速
| 硬件 | 效果 |
|---|---|
| SSD/NVMe | 减少 I/O 等待,可节省 30-50% 时间 |
| 更多内存 | 避免 swap,建议 16GB+ |
| 更多 CPU 核心 | 放大-j并行效果 |
7.自定义GCC
自己改写GCC,这时需要用到增量编译,ninja就非常好用了,或者使用ccache。
这是大佬做的事,小弟我做不到。
8.GCC也分前后端
a.后端代码在哪里?
位于gcc/config/目录下,按架构分子目录:
| 架构 | 目录路径 |
|---|---|
| x86/x86-64 | gcc/config/i386/ |
| ARM | gcc/config/arm/ |
| AArch64 | gcc/config/aarch64/ |
| RISC-V | gcc/config/riscv/ |
| PowerPC | gcc/config/rs6000/ |
| LoongArch | gcc/config/loongarch/ |
b.后端包含哪些文件?
| 文件类型 | 示例 | 作用 |
|---|---|---|
| 机器描述文件 | riscv.md | 指令模式定义(后端核心) |
| C语言头文件 | riscv.h | 宏定义,如TARGET_CPU_CPP_BUILTINS() |
| C语言源文件 | riscv.c | 后端函数实现,如参数传递规则 |
| 目标选项文件 | riscv.opt | 架构特有命令行选项,如-march=rv64gc |
| 机器模式定义 | riscv-modes.def | 特殊机器模式(如条件码) |
| Makefile片段 | t-riscv | 该后端特定的构建规则 |
c.后端是预编译好的吗?
不是预编译的。
后端以源码形式存在于 GCC 源码包中
编译时根据
--target参数按需选取对应架构的后端源码被选中的后端源码会与前端、中端代码一起,静态链接到最终的
cc1、cc1plus等编译器可执行文件中
d.前端代码在哪里?
GCC 源码中,每个支持的语言都有一个对应的前端子目录,位于gcc/下:
| 语言 | 前端目录 | 核心文件 |
|---|---|---|
| C | gcc/c/ | c-parser.c,c-decl.c,c-typeck.c |
| C++ | gcc/cp/ | parser.c,decl.c,pt.c(模板处理) |
| Fortran | gcc/fortran/ | parse.c,resolve.c |
| Go | gcc/go/ | go-frontend/ |
| D | gcc/d/ | d-frontend.cc |
| Rust(GCC 16新增) | gcc/rust/ | rust-parse.cc |
| Ada | gcc/ada/ | par_sco.adb |
| Modula-2 | gcc/m2/ | m2-parse.cc |
e.前后端大概了解
源代码 (C/C++/Rust/...) ↓ ┌──────────────┐ │ 前端 │ ← 词法分析、语法分析、语义分析 │ (Frontend) │ 输入: 源代码 (.c, .cpp, .rs) └──────────────┘ 输出: GENERIC / GIMPLE (中间表示) ↓ ┌──────────────┐ │ 中端 │ ← 机器无关优化 (内联、常量传播、死代码消除等) │ (Middle) │ 输入: GENERIC / GIMPLE └──────────────┘ 输出: GIMPLE / RTL ↓ ┌──────────────┐ │ 后端 │ ← 指令选择、寄存器分配、指令调度 │ (Backend) │ 输入: RTL └──────────────┘ 输出: 汇编代码 / 机器码 ↓ 可执行文件新增一门语言时,开发者只需要写一个新的前端,中端和后端完全不用改
支持一个新架构时,只需要写一个新的后端,所有语言的前端都能受益
五、速成
基础指令(仅Ubuntu):
# 安装库 sudo apt update sudo apt install -y build-essential python3 libgmp-dev libmpfr-dev libmpc-dev \ binutils libc6-dev zlib1g-dev libssl-dev pkg-config # 设置版本号(根据需要修改) GCC_VERSION=14.2.0 # 下载源码(建议使用镜像源) # wget https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.gz wget / https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.gz # 解压 tar -xzf gcc-${GCC_VERSION}.tar.gz # 进入源码目录 cd gcc-${GCC_VERSION} # 自动下载 GMP、MPFR、MPC 等依赖(如未通过包管理器安装) ./contrib/download_prerequisites # 创建临时构建目录build mkdir build && cd build # 构建prefix目录 sudo mkdir /usr/local/gcc2 # 配置(加速版,ld.gold) ../configure \ --prefix=/usr/local/gcc2 \ --enable-languages=c,c++ \ --enable-lto \ --disable-multilib # 并行编译(使用所有 CPU 核心) make -j$(nproc) # 安装到 --prefix 指定的目录 sudo make install # 将新 GCC 加入 PATH(永久生效) echo 'export PATH=/usr/local/gcc2/bin:$PATH' >> ~/.bashrc # 使配置立即生效 source ~/.bashrc # 查看版本 gcc --version g++ --version # 查看路径 which gcc # 查看链接器(如使用了 ld.gold) ldd $(which gcc) | grep gold # 删除源码和构建目录(节省空间) cd ../.. rm -rf gcc-${GCC_VERSION} gcc-${GCC_VERSION}.tar.gz一键脚本(仅Ubuntu):
#!/bin/bash # compile_gcc.sh - 一键编译安装 GCC set -e # 遇到错误立即退出 # 配置参数 GCC_VERSION="14.2.0" PREFIX="/usr/local/gcc2" JOBS=$(nproc) # 1. 安装依赖 sudo apt update sudo apt install -y build-essential python3 libgmp-dev libmpfr-dev libmpc-dev \ binutils libc6-dev zlib1g-dev libssl-dev pkg-config # 2. 下载源码 wget / https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.gz tar -xzf gcc-${GCC_VERSION}.tar.gz cd gcc-${GCC_VERSION} # 3. 下载依赖(不必) # ./contrib/download_prerequisites # 4. 配置 mkdir build && cd build sudo mkdir /usr/local/gcc2 ../configure \ --prefix=${PREFIX} \ --enable-languages=c,c++ \ --enable-lto \ --disable-multilib # 5. 编译 make -j${JOBS} # 6. 安装 sudo make install # 7. 配置环境 echo "export PATH=${PREFIX}/bin:\$PATH" >> ~/.bashrc source ~/.bashrc # 8. 验证 gcc --version g++ --version echo "GCC ${GCC_VERSION} 安装完成!"