本文由Markdown语法编辑器编辑完成。
1.背景:
最近在Ubuntu系统下学习Matlab中一些机器学习的算法。Matlab是之前用光盘iso的形式安装好的 2018a的版本。
现在希望将一些之前撰写的Matlab的源代码(以.m后缀名命名的函数文件),通过Matlab的编译环境(Matlab Compiler)来生成,可供C语言调用的.h和.so文件。
然而,在使用Matlab Compiler,在命令行窗口调用mcc指令时,会弹出提醒,Matlab 2018a, 仅支持gcc 6.3.0的底层编译环境。但是Ubuntu 18.04自带的gcc的版本,是高于gcc 6.3.0的。我的机器里面,gcc的版本是7.5.0.
而且,Ubuntu 18.04的包管理器中,如果直接安装gcc 6的话,安装完成的gcc版本,是gcc 6.5.0, 也是高于Matlab 2018a Compiler要求的gcc 6.3.0的。
最终在问了一些相关的网站论坛和AI后,给出的方法是,自己下载gcc 6.3.0的源码,在本机环境下编译和安装。
在编译的过程中,遇到了各种各样的问题,几度要放弃。以下是做过的一些其他尝试:
方法 | 尝试方法 | 结果 |
---|---|---|
1 | Ubuntu 18.04, 手动下载和编译gcc 6.3.0 | 中途报错,几度放弃 |
2 | Ubuntu 18.04, 安装Matlab 2019a, 企图2019a用的gcc版本会高一些,这样就不需要自己编译gcc 6.3.0 | linux下面安装Matlab2019a, 失败,放弃 |
3 | Ubuntu 24.04, 直接安装Matlab 2025a的 docker image. | 2025a 的Matlab镜像,只有最简单的计算功能,高级功能都没有,特别是Matlab coder, Matlab compiler工具 |
4 | Ubuntu 24.04, 直接安装Matlab deep learning 2025a的docker image. |
在综合比较了以上的四个方案后,第3,4两个方案,已经明确验证了,无法满足自己使用mcc指令的需求。第2个安装,受困于安装2019a时的各种报错,还是弃了。
最后,华山一条路。只能硬着头皮,继续攻克,在Ubuntu 18.04上面,编译gcc 6.3.0的阻挠了。
最终还是,功夫不负有心人,终于成功地完成了。
以下介绍如何在Ubuntu 18.04的环境下面,通过源码编译gcc 6.3.0的经验。
2. 编译过程
编译过程中,最令人想放弃的时刻,就是在make过程中,弹出的报错。因为涉及到了源码的修改,因此需要比较谨慎。
在编译的过程中,主要是求助google搜索,豆包,kimi, chatgpt和claude等几款AI工具的帮助。
网络上,关于如何在Ubuntu 18.04上面编译gcc 6.3.0, 有基本的步骤说明,见博客:https://congyewang.github.io/posts/gcc6_compiling/
该博客介绍了基本的过程,但是在一些关键的步骤中,缺乏相应的运行截图。这样在编译过程中,遇到了报错,也无法对应解决。
就像科研论文一样,如果在论文中介绍的步骤太粗略的话,最终实验得到的结果,如果别人无法按照你的步骤,稳定地重现结果的话,论文是可能被打回的。
因此,我希望通过我的演示,能够真正地重复稳定地实现这个过程。大致的流程,是通过向Claude提问后,得到的,以下是回答截图:
2.1 准备过程 -> 安装相关依赖,源码,解压
安装依赖:
sudo apt-get update
sudo apt-get install build-essential wget m4 flex bison
下载源码和解压
wget https://ftp.gnu.org/gnu/gcc/gcc-6.3.0/gcc-6.3.0.tar.gz
tar xf gcc-6.3.0.tar.gz
cd gcc-6.3.0
以上两步还比较顺利。
接下来的步骤, Download prerequisites时遇到了困难。
运行:
./contrib/download_prerequisites
说实话,这还是我在写这次博文时,又运行这条命令时,才成功了这么一次。就是运行: ./contrib/download_prerequisites这句话没有报错的。
之前每次运行这条指令,都会报错,一般是报连接被拒绝, Connecion refused的错误。
如果遇到报错,就需要自己手动wget下载这些必须的依赖包了。具体的指令为:
首先返回到gcc-6.3.0源码的上一层,来下载和解压这些依赖包。
cd ..
wget https://gmplib.org/download/gmp/gmp-6.1.0.tar.bz2
wget https://www.mpfr.org/mpfr-3.1.4/mpfr-3.1.4.tar.bz2
wget https://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz
wget https://gcc.gnu.org/pub/gcc/infrastructure/isl-0.16.1.tar.bz2
# 解压
tar xf prerequisites/gmp-6.1.0.tar.bz2
tar xf prerequisites/mpfr-3.1.4.tar.bz2
tar xf prerequisites/mpc-1.0.3.tar.gz
tar xf prerequisites/isl-0.16.1.tar.bz2
mv gmp-6.1.0 gmp
mv mpfr-3.1.4 mpfr
mv mpc-1.0.3 mpc
mv isl-0.16.1 isl
# 再将这几个文件夹,拷贝到gcc-6.3.0的源码中。
mv gmp mpfr mpc isl ./gcc-6.3.0/
2.2 项目配置 -> config, make, install
在gcc-6.3.0的源码的上一层,和gcc-6.3.0同级,创建一个gcc-6.3.0-build的文件夹,用来存放编译过程中的文件。这样即使出错了,也可以直接删除这个build的目录,重新构建。
我在编译的过程中,前后差不多创建和删除了,十几次这个build的文件夹。
mkdir gcc-build
cd gcc-build
CFLAGS="-fPIC" \
CXXFLAGS="-fPIC -fpermissive" \
../gcc-6.3.0/configure \
--prefix=/usr/local/gcc-6.3.0 \
--enable-languages=c,c++ \
--disable-multilib \
--disable-bootstrap \
--with-system-zlib \
--enable-shared \
--disable-checking \
--build=x86_64-linux-gnu
make CXXFLAGS="-O2 -fpermissive" -j4
在运行make -j4, (j后面的数字,可以根据自己的服务器有几核来修改。-j4, 代表是占用四个CPU的核来编译。)
编译过程中的报错如下:
咨询chatgpt后,给出的解释是:
根据给出的解决方案,我开始在gcc-6.3.0的源码中进行修改。
但是增加了这个头文件的定义后,删除gcc-build. 又重新创建了一个新的gcc-build的文件夹,再次重复刚才的config和make, 结果过了一会后,还是报错了。
这次再次拷问chatgpt, 它给我的回复是:
因此,我便又找到gcc-6.3.0的源代码,进行修改:
源码的位置在: gcc-6.3.0/libgcc/config/i386/linux-unwind.h的第68行。
修改第68行,结构体的定义为:
经过上述的修改。再次删除之前的gcc-build的文件夹。再重新mkdir gcc-build, 重复上一次的config和make, 又遇到了新的报错。
不过这次的报错,和上次的报错位置,已经不同了。说明上一次的修改,已经发挥了作用。向着成功又迈进了一步。
然后这个新报出来的错误,我却前前后后改了七八次源码,都是没有通过make。
正当我绝望,又准备放弃这次的尝试时。chatgpt给了我一个回复说:
当它给了我两个方案,并且第一个方案是,直接在config的时候,通过禁用 libsanitizer组件,来达到目的的。我总算看到了一些希望。
于是在经过十几次的源码修改后,我终于修改了config的配置,如下:
CFLAGS="-fPIC" \
CXXFLAGS="-fPIC -fpermissive" \
../gcc-6.3.0/configure \
--prefix=/usr/local/gcc-6.3.0 \
--enable-languages=c,c++ \
--disable-multilib \
--disable-bootstrap \
--with-system-zlib \
--enable-shared \
--disable-checking \
--disable-libsanitizer \ # 这一行是新增的。禁用该组件后,再make就可以成功了。
--build=x86_64-linux-gnu
然后再运行:
make CXXFLAGS="-O2 -fpermissive" -j4
很快就make通过了。
make通过后,就是install了。运行如下指令:
sudo make install
运行完成后,即完成了gcc 6.3.0的编译和安装。运行完毕后,gcc6.3.0 被安装在了: /usr/local/gcc-6.3.0目录下面。
接下来就是将gcc6.3.0加入到环境变量中,输入:
echo 'export PATH=/usr/local/gcc-6.3.0/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/gcc-6.3.0/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
后,如果输入:
gcc-6 --version
显示的是:
则说明,已经成功地编译和安装了 gcc 6.3.0.
3. 重要补充:
原本以为在Matlab 2018a下面,必须使用gcc 6.3.0的版本,才能使用mcc, 将.m文件,转化为.h和.so文件。
但是经过我的实际测试,这个实际并不是必须的。使用高于6.3.0版本的gcc, 也是可以的。只不过是在Matlab 2018a的command window中,生成文件时会报警告。
测试如下,打开Matlab 2018a的命令窗口,首先我创建了一个测试两个数相减的函数,名称为: substract.m.
如下:
function c = substract(a, b)
% Substract two numbers
c = a - b;
end
然后在matlab的command窗口中输入:
mcc -W cpplib:libsubstract -T link:lib substract.m
虽然出现了这个提示,但是过了一会儿,还是在当前目录下面,生成了.h和.so文件。如下图所示: