目前在虚拟机中安装了Debian 12.7,使用apt安装的build-essential中默认的GCC版本是12.2.0,如需安装GCC13+版本可以使用源代码自行构建。

1 准备源代码

下载并解压源代码,这里选择更新到13.3.0版本。

1
2
wget https://ftp.gnu.org/gnu/gcc/gcc-13.3.0/gcc-13.3.0.tar.gz
tar -xvf gcc-13.3.0.tar.gz

2 安装依赖

首先确保使用apt安装了基本的编译环境。

1
sudo apt update && sudo apt install -y build-essential libgmp-dev libmpfr-dev libmpc-dev gcc-multilib

然后下载GCC 13.3.0编译过程中需要的依赖。

1
2
cd gcc-13.3.0
./contrib/download_prerequisites

3 编译安装

根据GCC文档的说明,不能在代码所在目录gcc-13.3.0编译,应当创建一个和代码同级的目录生成Makefile文件,这里创建gcc-build目录。

1
2
3
# 回到 gcc-13.3.0 所在的 home 目录后创建 gcc-build
cd ~
mkdir gcc-build

创建后的目录结构应为:

1
2
3
4
.
├── gcc-13.3.0
├── gcc-13.3.0.tar.gz
├── gcc-build

运行配置程序生成Makefile,同样根据GCC安装文档,这个步骤不要添加过多自己不清楚是干什么的参数。

1
2
3
# 进入 gcc-build 目录后使用 configure 生成 Makefile
cd gcc-build
../gcc-13.3.0/configure --enable-languages=c,c++

3.1 编译

这个过程可能会非常慢,取决于硬件条件,使用虚拟机的话可以临时把CPU和内存都调到最大。我在虚拟机中编译,AMD R7-6800H内核分配16,内存分配8G,编译时间大约55分钟。

1
make -j$(nproc)

编译过程中可能会出现错误,大多数情况是因为缺少依赖,根据报错信息搜索安装对应的依赖即可。编译中断后,可以在gcc-build目录中重复执行make -j$(nproc)命令,已经编译过的文件不会再次编译,幸运的话可以节省一些时间。

不过仍然建议出错中断后,删除gcc-build文件夹后彻底重新编译。

3.2 安装

这一步也会花费一些时间,但是比编译要快得多。在configure时没有指定--prefix参数,默认安装到了/usr/local/bin。向/usr/local/bin目录写入文件需要使用sudo

1
sudo make install

3.3 添加动态库的路径

安装完成后会看到终端中有类似这样的提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Libraries have been installed in:
/usr/local/lib/../lib64

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.

这是提示我们新的GCC的动态库安装在了/usr/local/lib/../lib64路径下,需要通过给出的方法中的至少一种,将这个路径添加到动态库搜索路径中。

可以选择修改环境变量的方式修改:

1
2
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/../lib64
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/../lib32

将上面两条命令写入终端配置文件(如.bashrc.zshrc等),可以实现永久配置。

也可以选择修改/etc/ld.so.conf配置文件,需要使用sudo,新加入的路径放在上面会优先于原来的路径查找:

1
2
3
4
5
6
# 原文件
include /etc/ld.so.conf.d/*.conf
# 修改后
/usr/local/lib/../lib64
/usr/local/lib/../lib32
include /etc/ld.so.conf.d/*.conf

修改/etc/ld.so.conf配置文件后,需要使用sudo ldconfig命令刷新。

程序在使用新的GCC编译之后,运行时如果报错version GLIBCXX_X.X.X' not found,大概率是这一步设置没有做对。

使用ldd ./a.out查看编译出的可执行文件的动态库依赖关系,可以检测动态库搜索路径是否正确。

4 更新软连接

虽然已经编译安装完成,但使用gcc -v命令查看版本还没有更新,还需要修改gccg++命令的软连接,将其指向我们刚编译安装的/usr/local/bin/gcc/usr/local/bin/g++

如果经常需要切换版本,可以使用使用update-alternatives来管理不同的版本,这里简单起见,直接修改软连接。

查看旧版本的GCC所在的路径

1
2
3
4
5
6
7
which gcc
# /usr/bin/gcc
ls -l /usr/bin/gcc* /usr/bin/g++*
# /usr/bin/g++ -> g++-12
# /usr/bin/g++-12 -> x86_64-linux-gnu-g++-12
# /usr/bin/gcc -> gcc-12
# /usr/bin/gcc-12 -> x86_64-linux-gnu-gcc-12

可以发现原本的gcc命令也是一个软连接,指向另一个软连接gcc-12,而gcc-12指向了真正的可执行文件x86_64-linux-gnu-gcc-12g++命令也是一样。

现在删除原本的gccg++

1
sudo rm /usr/bin/gcc /usr/bin/g++

新建指向/usr/local/bin/gcc/usr/local/bin/g++gccg++

1
2
sudo ln -s /usr/local/bin/gcc /usr/bin/gcc
sudo ln -s /usr/local/bin/g++ /usr/bin/g++

此时就可以使用gcc -v验证更新后的版本了。

5 删除文件

使用新的GCC编译一个程序,并且该程序能正常运行。简单测试一下安装正常之后,可以删除GCC编译后产生的文件,位于目录gcc-build;GCC代码文件,位于目录gcc-13.3.0;GCC代码压缩包gcc-13.3.0.tar.gz

1
rm -rf gcc-build gcc-13.3.0 gcc-13.3.0.tar.gz

至此GCC更新完成。

6 参考


本站由 @gsh1209 使用 Stellar 主题创建
Copyright © 2023 - BG3LNT.XYZ
Favicon图标来自 @ChenCJ
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处
正在计算运行时间...

蒙ICP备2022000455号-2