作者: bzhaoopenstack
在ARM平台上如何愉快的切换perl版本,给自己的项目提供方便,请看过来。
在ARM平台上玩转perl
最近在给开源项目接入ARM CI的工作中,遇到了很多问题。因为一般开源的主战场都在github,几乎所有在github上开源的项目在做自己的自动化构建时都会知道一个名字travis
, 作为github上首屈一指的自动化构建平台,travis
也是唯一一家支持ARM自动化构建的。所以,在给使用travis
的开源项目接入ARM自动化构建平台时,我们往往也会想到直接用travis
的ARM资源来进行构建。
但是,travis ARM 资源确实与AMD64资源相比差距比较大,注意,这里的差距比较大不是性能方面的,而是如下:
- Travis ARM资源缺少很多基本库,原因之一是很多基本库是支持X86的,但是在aarch64平台上travis ARM测试床没有做很好的适配。
- Travis build-in的工具没有及时跟进ARM平台,导致很多在X86平台已经配置好的travis job不能平滑的迁往ARM。即便项目是基于上层语言(Java/Python)。
- 由于Travis CI系统非常庞大,周边使用它的github项目也非常多,所以往往造成它的支撑团队没有足够的精力来处理成吨的需求,所以往往对于当前还处于成长期的ARM平台/资源来说,优先级可想而知。所以这会造成对于ARM的需求,无法很及时的响应。
根据上面的问题,我们主要举几个例子:
例如在travis job配置过程中,用的ubuntu镜像,在使用apt安装某一个软件时,在X86正常安装,但是在ARM平台上报找不到包。这个时候就必须在ARM的travis job中手动换源,换成包含这个包的ubuntu源。
对于build-in工具,拿个最近遇到的case来举例:
a. travis openjdk-ea安装。
我们知道在travis测试环境中安装jdk,travis是有通用字段可以描述的,看这里。但是在ARM平台上就是装不了,是因为它内建的工具大部分没有做ARM适配,比如在这里遇到的
jdk_switcher
, 在ARM的ubuntu镜像里没有安装这个工具。所以给了接入travis ARM CI一定的难度。有两个方案:1). 推动上游travis支持。— 太慢
2). 手动模拟travis行为,尽可能模仿,一旦将来travis完善了,也能做到平滑迁移。
当然,这两个方案可以同时进行,现在travis上游提出需求,同时在对想接入travis ARM CI的项目进行适配。这里我们找到了对应问题的项目:
jdk_switcher 和 安装不同版本jdk的install-jdk.sh,比较幸运的是,后者还有人维护,并且新版本开始支持ARM平台的jdk版本下载及安装。所以在项目接入过程中,手动进行ARM适配。
接下来,介绍的perl在ARM上的精力也是在调试travis ARM CI过程中遇到的,所以为了一次捋顺,让我们看看如何搞。
我们用ubuntu bionic环境来举例。以下对于选用多个perl版本的项目比较有用。我们将会用到多个工具,我会做简要的介绍。
通常在ubuntu内建的软件包中都会含有perl,因为在apt-get工具对perl有强依赖,所以在安装和更新perl,甚至是替换which perl
目录的软连接需要小心,你可能在破坏apt-get工具的依赖,导致apt-get都用不了。
这里我们先用系统内建的perl来安装后面我们需要的工具,如:
perlbrew 可以用源码方式安装perl的各种版本,可以容纳多个perl版本共存,并随意切换。
cpan 用于安装perl module的工具,比较古老,并且内置的cpan工具不太好用,而且做不到版本隔离。
cpanm 克服了cpan的一系列缺点,相当好用。
首先通过内建的cpan安装perlbrew,因为内建的perl是与cpan关联的,由它开始是最为稳妥的办法,直接以源码或deb/yum包安装perl很快就会让你抓耳挠腮。命令如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27# 由内建的cpan工具安装perlbrew,与内建的perl关联
echo "yes" | sudo cpan App::perlbrew ;
# 初始化,在用户家目录下导入必备的环境变量等等
perlbrew init ;
# 导入当前perlbrew的环境变量,为了确保我将它写在了~/.bashrc里
source ~/perl5/perlbrew/etc/bashrc ;
cat ~/perl5/perlbrew/etc/bashrc >> ~/.bashrc ;
# 查看现在可用的所有perl版本
perlbrew available
# 下载并安装对应的版本,它会默认安装到~/perl5目录下,并且以版本号区分好,真正引用的时候可以用perlbrew非常方便的切换
perlbrew install 5.18.2
perlbrew install perl-5.8.1
perlbrew install perl-5.19.9
# 查看已安装在本地的perl列表
perlbrew list
# 设置默认使用的perl版本,注意,这个不影响apt-get命令,因为所有的bin/lib都是与其分开的
perlbrew switch perl-5.18.2
# 暂时切换使用的perl版本,比如在一个shell脚本里,切换完成后,你可以查看perl当前的版本是否对应
perlbrew use perl-5.8.1
perl -v下面在通过perlbrew安装cpanm,不要简单的认为,你能从apt-get 或者 官方脚本下载安装,这样非常不安全,因为如果从apt-get下载会与内建的perl耦合,非常影响后续的测试,官方脚本下载安装会重新创建一个新的perl运行环境,与之前利用内建cpan安装的perlbrew环境是隔离的,对之后版本切换以及perl module安装配置会很麻烦。所以,我们需要利用第一步安装的perlbrew来安装cpanm,这样既不破坏内建perl又能做到隔离,避免后续相当麻烦的配置工作。
1
perlbrew install-cpanm ;
cpanm已经安装好后,下面我们可以根据不同版本的perl来安装不同的perl module环境,类似于python的虚环境。
1
2
3
4
5# 安装local::lib并切换导入的lib路径,你完全可以自定义。
cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
# 用cpanm安装一个perl module,后面的-n表示不执行测试进行安装,主要是为了提升安装速度。
cpanm IPC::Run -n
在最后,提醒一点,这样操作后,你可以在编译基于perl的项目时仍然遇到缺少perl module的情况,如缺少XXX.pm等等,那是因为上面只是给当前运行的perl导入了lib路径,在编译是你仍然需要做的是, 导入LD_LIBRARY_PATH,举个我在编译PG时的例子:
1 | export LD_LIBRARY_PATH=$HOME/perl5/lib/perl5/ |
好了,以上就可以用perl在ARM平台上快乐的玩耍了,非常方便易用。