在ARM平台上玩转perl

作者: bzhaoopenstack

在ARM平台上如何愉快的切换perl版本,给自己的项目提供方便,请看过来。

在ARM平台上玩转perl

最近在给开源项目接入ARM CI的工作中,遇到了很多问题。因为一般开源的主战场都在github,几乎所有在github上开源的项目在做自己的自动化构建时都会知道一个名字travis , 作为github上首屈一指的自动化构建平台,travis也是唯一一家支持ARM自动化构建的。所以,在给使用travis的开源项目接入ARM自动化构建平台时,我们往往也会想到直接用travis的ARM资源来进行构建。

但是,travis ARM 资源确实与AMD64资源相比差距比较大,注意,这里的差距比较大不是性能方面的,而是如下:

  1. Travis ARM资源缺少很多基本库,原因之一是很多基本库是支持X86的,但是在aarch64平台上travis ARM测试床没有做很好的适配。
  2. Travis build-in的工具没有及时跟进ARM平台,导致很多在X86平台已经配置好的travis job不能平滑的迁往ARM。即便项目是基于上层语言(Java/Python)。
  3. 由于Travis CI系统非常庞大,周边使用它的github项目也非常多,所以往往造成它的支撑团队没有足够的精力来处理成吨的需求,所以往往对于当前还处于成长期的ARM平台/资源来说,优先级可想而知。所以这会造成对于ARM的需求,无法很及时的响应。

根据上面的问题,我们主要举几个例子:

  1. 例如在travis job配置过程中,用的ubuntu镜像,在使用apt安装某一个软件时,在X86正常安装,但是在ARM平台上报找不到包。这个时候就必须在ARM的travis job中手动换源,换成包含这个包的ubuntu源。

  2. 对于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的一系列缺点,相当好用。

  1. 首先通过内建的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
  2. 下面在通过perlbrew安装cpanm,不要简单的认为,你能从apt-get 或者 官方脚本下载安装,这样非常不安全,因为如果从apt-get下载会与内建的perl耦合,非常影响后续的测试,官方脚本下载安装会重新创建一个新的perl运行环境,与之前利用内建cpan安装的perlbrew环境是隔离的,对之后版本切换以及perl module安装配置会很麻烦。所以,我们需要利用第一步安装的perlbrew来安装cpanm,这样既不破坏内建perl又能做到隔离,避免后续相当麻烦的配置工作。

    1
    perlbrew install-cpanm ;
  3. 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export LD_LIBRARY_PATH=$HOME/perl5/lib/perl5/
sudo apt install libperl-dev -y
cd
git clone https://github.com/postgres/postgres
cd postgres
./configure --prefix=$HOME/pgsql-install --enable-tap-tests --with-perl
make -j
make install

## Fix
#pg@pg-test:~/postgres/src/bin/pg_basebackup$ pg_recvlogical -S test -d postgres --create-slot
#pg_recvlogical: error: could not send replication command "CREATE_REPLICATION_SLOT "test" LOGICAL "test_decoding" NOEXPORT_SNAPSHOT": ERROR: could not access file "test_decoding": No such file or directory
cd contrib/test_decoding/
make all
cp test_decoding.so `pg_config --pkglibdir`

export PGDATA=$HOME/pgsql-install/data
export LD_LIBRARY_PATH=$HOME/pgsql-install/lib:$LD_LIBRARY_PATH
export PATH=$PATH:$HOME/pgsql-install/bin/
which psql
psql --version

好了,以上就可以用perl在ARM平台上快乐的玩耍了,非常方便易用。

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×