自己动手编译 GCC!
因为我们学校里的在线评测系统没有办法屏蔽 #pragma GCC optimize
预处理指令,因此出现了如下的状况:
因此,今天我决定从根源上禁止这些行为。
正好前两天看到洛谷上屏蔽手动 O2 O3 Ofast 的方式,于是今天自己就来试着修改 GCC
的源代码,并计划手动编译并上线测试。
需求整理
- 魔改编译器禁止手动优化;
- 编译器版本之间可以分离,不予系统自带的编译器冲突;
GCC 9
+GCC 12
。
准备工作
如果你也是某个 OJ 的运维/管理,直接在服务器上构建源代码会更好,但是注意资源占用。
如果你只是自用,那么无所谓。
但是前提是一定要在一个 Linux 环境下操作。(我也只写了 Linux (Ubuntu) 的记录啥的)
正式安装
安装需要的库
文档是按照最新的正式版 GCC 12
写的,向下兼容。
根据 Prerequisites for GCC 所说,总结下来,最省心的情况(我的情况)需要如下条件:
- 通常是系统自带的
- Ubuntu >= 20.04 (当然可以不是这个发行版,但
CentOS
算了) - 一个 POSIX Shell,但不包括
zsh
。 - GCC >= 9.4
- Python 3
- ssh, git 等
- Ubuntu >= 20.04 (当然可以不是这个发行版,但
- 需要手动构建安装的
安装依赖库的过程相对简单。步骤总价下来无外乎以下几点:
1. 下载依赖库源码包
2. 上传源码包到服务器
3. 解压源码包
4. cd
到源码包解压到的目录
5. 执行:./configure && make && sudo make install
一定要从上往下依次安装。
配置
现在假定你的源代码存放在 src
目录下。在 src
的上级菜单新建文件夹 obj
。
/path/to/your/project
|--- src
|--- configure
`--- [Another Files]
`--- obj
在 obj
目录下执行 configure
指令。
比方说,我的指令是:
../src/configure --with-pkgversion="gcc-12.2.0_Imken_Customized (Build On JudgeMachine)" --host=x86_64-pc-linux-gnu --disable-multilib
(32 位机器大概不适用)
--with-pkgversion
指 g++ --version
时显示的版本号(下面括号里的内容),具体如下:
$ g++ --version
g++ (gcc-12.2.0_Imken_Customized (Build On JudgeMachine)) 12.2.0
Copyright (C) ...
--host=x86_64-pc-linux-gnu
是说目标平台的架构。
更多配置项目参见 Installing GCC: Configuration。
构建
本过程大约需要 0.6 ~ 4 小时。期间服务器的资源会爆满。建议使用 screen
在后台运行。
构建很简单,在 obj
文件夹下执行 make
即可。或者说,机子够强,可以并行构建,执行 make -j <线程数>
即可。
然后就是艰难的等待。我个人建议在机子终端面前守着,防止意外错误。
我遇到了一个错误,libgsl.so.23
没找到。这个 issue 解决得还不错,就是修改 ld
寻找 so
文件的目录。
LD_LIBRARY_PATH=/usr/local/lib/
export LD_LIBRARY_PATH
若构建中断,可以从断点重新开始构建。make
还是比较智能的。
安装
要是不出意外的话,构建将会在很长一段时间之后结束。此时可以执行 make install
。
但!是!我要版本隔离!
make DESTDIR=<目标目录> install
可以让 GCC
安装在指定目录。比如:
make DESTDIR=/opt/imken_oi/gcc/1220 install # GCC 12.2.0
make DESTDIR=/opt/imken_oi/gcc/940 install # GCC 9.4.0
目录不存在的话会自动新建。
安装好的 GCC
的 bin
在 <DESTDIR>/usr/local/bin/
。
总结
等死我了。最后 make install
的可执行文件对于每一台机子都不一样,不可直接复制构建出来的文件。烦死了。白编译三个小时。
更新信息
Update at 2023/5/10: Fix typo
rickyxrc
2023年5月9日 @ 21:55
“总结”段落中发现错别字,应为“移植”并非“一直”
Imken Luo
2023年5月10日 @ 13:51
感谢 已更正
等待 CDN 缓存刷新