Rust在CentOS 6上的移植
Rust已不支持Cent OS 6
rhel是Redhat 发布的Red Hat Enterprise Linux的简称,使用rhel源代码编译的CentOS,最新的版本是CentOS 7,于2024年停止支持。而更古老的CentOS 6,则在2020年就已经结束了。
而面对如此老旧的系统,Rust官方则早就放弃了支持。
按照rust官网上的安装方法,执行:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
会首先返回一个curl不支持--proto
,把这行删掉再执行,成功下载了rustup.rs,则会直接失败在不支持的glibc版本这一步上。
通过2022年8月1日这则blog,我们知道Rust已经从1.64版本开始,明确放弃了对glibc 2.17版本、linux 3.2版本之下的支持(以前的版本是glibc 2.11、linux 2.6.32)。
而Cent OS 6的glibc的版本是2.12.1,linux的版本是2.6.32。所以,我们只能选择rust 1.63版本。
安装 Rust 1.63
好在Rust很良心地提供了各平台安装包,在归档里就有Rust 1.63。
因为是Linux系统,我们选择x86_64-unknown-linux-gnu下载,放到Cent OS 6系统上。
解压开之后,会有一个install.sh
。执行完之后,1.63版本的Rust就安装好了。
默认地,它会安装在/usr/local
目录里,所以我们熟悉的cargo、rustc、rustfmt等命令,都会在/usr/local/bin
目录里。如果/usr/local/bin
没有在PATH环境变量的,需要加一下。
如:
export PATH=/usr/local/bin:$PATH
gcc 4.8
如果我们使用的crates也都比较老旧,这时候在CentOS 6上已经可以“比较顺畅”地使用Rust开发了。
但是,现在毕竟已经是2025年了,C++已经经过了C++ 11、C++ 14、C++ 17、C++ 20以及C++ 23,就要发布C++ 26了。而CentOS 6上的gcc 还是4.4.7,连C++ 11都不支持。
好在Redhat提供了devtoolset。对于Cent OS 6来说,最简单方便地使用devtoolset 的方法,就是直接在/etc/yum.repos.d里,手动增加一个devtoolset 2的repo文件。
[devtools-2-centos-$releasever]
name=devtools 2 for CentOS $releasever
baseurl=http://people.centos.org/tru/devtools-2/$releasever/$basearch/RPMS
gpgcheck=0
然后运行yum repolist
,就会增加一个repo,名字叫做devtoolset 2 for CentOS 6
,我们执行yum search devtoolset
,可以看到gcc、gdb、valgrind等一系列开发工具,甚至包括Emacs,都有了devtoolset 2的定制版本。
我们安装yum install devtoolset-2-gcc
之后,会发现这些东西安装在了目录/opt/rh/devtoolset-2/root
里面。
为了方便,我们可以把原来的gcc备份一下,然后建一个新的软连接,连接到devtoolset-2的gcc。
mv /usr/bin/gcc /usr/bin/gcc-4.4.7
ln -s /opt/rh/devtoolset-2/root/usr/bin/gcc /usr/bin/gcc
之后执行gcc -v
,就可以看到gcc 已经升级到4.8.2版本了。
虽然gcc 4.8也已经被放弃支持了,但是毕竟它支持std=c1x
啊。
rustup 切换到1.63
如果我们已经不习惯在古老的CentOS 6系统里面开发,其实我们可以进行交叉开发。
即,在一个比较新的系统里,使用rust 1.63进行开发,然后再把代码放到CentOS 6里面进行编译。
得益于rustup的生态,进行这项工作非常简单。
首先,使用rustup安装1.63版本。
rustup intall 1.63.0
其次,在我们需要使用低版本rust的项目里执行:
rustup override set 1.63.0
之后就可以舒服的在高版本的Linux里开发低版本的rust程序了。
如果切换之后,提示
error: failed to parse lock file at: /home/p/Nutstore/jt/bjagent_gbjt/Cargo.lock Caused by: lock file version `4` was found, but this version of Cargo does not understand this lock file, perhaps Cargo needs to be updated?
就是当前的rust版本不支持Cargo.lock文件的格式,备份之后删除重试就行。
cargo 依赖
在使用rust 1.63的过程中,我还发现几个对我造成了困扰,但是其实又比较有意思的地方。
- cargo缓存的包会影响cargo程序运行
我的项目里面依赖了fastdate这个crate,这个crate依赖的Rust版本是2024,于是在我使用了rust 1.63的项目目录下面,连执行cargo tree
解析依赖树都解析不了,直接停止在rust不能解析fastdate 的Cargo.toml里的editon=2024这句。
即使我在Cargo.toml里面指定使用较低版本的fastdate,仍然解决不了这个问题。cargo仍然会解析高版本的fastdate,然后停止。
我是把.cargo/registry/src/
目录中的fastdate源码改了,才可以执行出来cargo tree
,进而发现是其它包间接依赖高版本的fastdate,才最终在项目上解决这个问题。
- cargo解决依赖关系的时候,会使用最新版本。
比如,你的项目里面使用了一个crate叫做a,因为比较新的a需要Rust 1.64,于是你使用了比较旧的a版本,并且在Carto.toml里使用
[dependencies]
a = "=old"
严格限制了版本号。
但是,如果a依赖了b,cargo在构建的时候,仍然会选择较新版本的b来构建。
于是构建失败。
其实解决方法也很简单,就是在Cargo.toml里,明确指定b的版本号。
- cargo提供了一个
minimal-versions
工具。
执行cargo install cargo-minimal-versions
安装,之后执行
cargo minimal-versions check
或者cargo minimal-versions build
来测试或者构建。
但是,其实这个命令还依赖cargo-hack
工具,需要再安装cargo install cargo-hack
。