使用 Cosmopolitan 的可移植 mruby 二进制文件
Source: Dev.to
背景
mruby 的主要吸引力之一是能够创建独立可执行文件。虽然这在很多情况下都能正常工作,但一个经典的限制是,大多数独立二进制文件只能在构建时所使用的相同或非常相似的系统上运行。例如,在 amd64 Linux 上构建的可执行文件在 Silicon Mac 上就无法运行:
$ ./hello
exec: Failed to execute process: './hello' the file could not be run by the operating system.
exec: Maybe the interpreter directive (#! line) is broken?
mruby 确实具备一些交叉编译能力,但这些能力往往让人望而生畏,并且常常难以正常工作(例如 Linux → macOS)。这就引出了一个问题:我们能否在不使用 macOS Docker 镜像的情况下构建真正可移植的 mruby 二进制文件?
Cosmopolitan Libc
在浏览 mruby 的更新日志时,我注意到一条记录:
New Platform: Cosmopolitan Libc
Cosmopolitan Libc 旨在让 C 成为一种“随处构建、随处运行”的语言,类似于 Java,但不需要解释器或虚拟机。它会重新配置 GCC/Clang,使其输出符合 POSIX 标准的多语言格式,能够原生运行在:
- Linux
- macOS
- Windows
- FreeBSD、OpenBSD、NetBSD
- BIOS(AMD64 与 ARM64)
性能接近原生水平。
使用 Cosmopolitan 构建 mruby
前置条件
-
下载 Cosmopolitan 工具集:
wget https://cosmo.zip/pub/cosmocc/cosmocc.zip unzip cosmocc.zip -d ~/Downloads/cosmocc -
确保工具集已解压到
~/Downloads/cosmocc(或相应地调整路径)。
步骤 1 – 构建 mruby
COSMO_ROOT=~/Downloads/cosmocc rake MRUBY_CONFIG=cosmopolitan
注意: 在撰写本文时,
mirb目标必须从配置中移除,因为它在 Cosmopolitan 下编译会失败。
步骤 2 – 生成字节码
使用 Cosmopolitan 专用的 mrbc 二进制:
./mruby/bin/mrbc.com -Bhello_world hello.rb
这会生成一个名为 hello_world 的 C 数组,里面包含编译后的 Ruby 字节码。
步骤 3 – 编译最终可执行文件
~/Downloads/cosmocc/bin/cosmocc -std=c99 -Imruby/include main.c \
-o hello mruby/build/host/lib/libmruby.a -lm
main.c是一个小的 C 入口文件,用来加载生成的字节码。- 生成的
hello二进制文件是一个 Cosmopolitan 可执行文件。
结果
生成的 hello 二进制文件可以在 Linux 和 macOS(包括 Apple Silicon)上直接运行,无需任何修改。该二进制文件比传统的 mruby 可执行文件要大,这是可移植性带来的代价,但在面向多平台分发时大大简化了工作流程。