Perl

RuxOS 支持在 Qemu 上运行 perl 程序。

实现方式:

为了在Rux OS操作系统上实现对perl语言的支持,首先利用了RuxOS已经集成的Musl-libc。Musl-libc是一个轻量级的C标准库,它为perl提供了必要的运行时环境。通过使用Musl-GCC编译器对perl的源代码进行编译,使得perl能够在RuxOS上运行。 将编译好的perl二进制文件以及它所需的所有动态库一起放入系统的root文件系统(rootfs)中。通过这种方式,perl可以在RuxOS上通过动态链接的方式运行。

简单测试程序:

第一步:

首先搭建好 RuxOS 的环境。

第二步:

进入RuxOS的根目录,输入以下命令,该命令将拉取 perl 相关的文件到 apps/c/rux-perl 目录下。并运行helloworld程序。

git clone https://github.com/syswonder/rux-perl.git ./apps/c/rux-perl
make A=apps/c/rux-perl ARCH=aarch64 V9P=y NET=y MUSL=y SMP=1 run

结果如下,会输出一行hello,perl!

8888888b.                     .d88888b.   .d8888b.  
888   Y88b                   d88P" "Y88b d88P  Y88b 
888    888                   888     888 Y88b.      
888   d88P 888  888 888  888 888     888  "Y888b.   
8888888P"  888  888 `Y8bd8P' 888     888     "Y88b. 
888 T88b   888  888   X88K   888     888       "888 
888  T88b  Y88b 888 .d8""8b. Y88b. .d88P Y88b  d88P 
888   T88b  "Y88888 888  888  "Y88888P"   "Y8888P" 

arch = aarch64
platform = aarch64-qemu-virt
target = aarch64-unknown-none-softfloat
smp = 1
build_mode = release
log_level = warn

[1716796042.017428 0 axfs_ramfs::dir:55] AlreadyExists sys
[1716796042.199408 0:2 ruxos_posix_api::imp::fd_ops:182] unsupported fcntl parameters: cmd 1
[1716796042.215760 0:2 ruxos_posix_api::imp::fd_ops:182] unsupported fcntl parameters: cmd 1
Hello, perl!

运行用户程序:

rux-perl的结构如下

rux-perl
├── axbuild.mk
├── config_linux.toml
├── features.txt
├── main.c
├── README.md
├── rootfs
│   ├── dev
│   ├── etc
│   ├── lib                         //perl所需的动态库
│   │   ├── ld-linux-armhf.so.3
│   │   └── ld-musl-aarch64.so.1
│   ├── perl                        //perl可执行文件
│   ├── proc
│   ├── sys
│   ├── tmp
│   ├── usr                         //perl所需的环境变量
│   │   └── local
│   │       └── lib
│   │           └── perl5
│   └── your_perl.t                 //默认运行的hello,perl程序
├── test_perl.sh
└── test.py

axbuild.mk中有一行:

ARGS = perl,your_perl.t

可以将 your_perl.t 换成想运行的xxx.t程序

perl的测试相关

因为RuxOS 目前并不支持fork() ,所以我用了一些方法来运行官方测试程序 如果你想运行perl的测试程序,首先将 main.c 中的一些注释给取消,这些是用于io重定向的 :

  // The following section of code is used only during Perl testing:

  // int fd = open("test_result.txt", O_WRONLY | O_CREAT | O_APPEND, 0644);
  // char *data = argv[1];
  // // wirte test filename
  // write(fd, "\n", 1);
  // write(fd, data, strlen(data));
  // write(fd, "\n", 1);
  // if (fd == -1) {
  //     perror("open failed");
  //     return 1;
  // }
  // // io redirect
  // if (dup2(fd, STDOUT_FILENO) == -1) {
  //     perror("dup2 failed");
  //     return 1;
  // }
  // chdir("/perl-5.38.2");

然后在RuxOS的根目录下运行:

sh apps/c/rux-perl/test_perl.sh

最后测试结构会保存在 /rux-perl/test_result.txt

测试脚本解释

test_perl.sh中首先会去下载 perl 的源码,这其中就包括了我们要运行的测试程序 然后调用test.py来进行测试 test.py中首先定义了要测试的文件夹,然后遍历文件夹,找到其中以 .t 为结尾的文件

folders = ["./apps/c/rux-perl/rootfs/perl-5.38.2/t/base"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/class"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/cmd"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/io"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/japh"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/mro"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/opbasic"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/re"
            ,"./apps/c/rux-perl/rootfs/perl-5.38.2/t/comp"]

然后对每个单独的 .t 文件都启动一个 RuxOS 来运行。

os.system(f"make A=apps/c/rux-perl ARCH=aarch64 V9P=y NET=y MUSL=y SMP=1 ARGS=perl,{file} run")

部分结果如下,会输出测试的脚本名称,以及测试的结果。

test result:
/perl-5.38.2/t/base/if.t
1..2
ok 1 - if eq
ok 2 - if ne

/perl-5.38.2/t/base/pat.t
1..2
ok 1 - match regex
ok 2 - match regex

/perl-5.38.2/t/base/while.t
1..4
ok 1
ok 2
ok 3
ok 4

...