虚無庵

徒然なるままに

Alpine Linux で ruby build

bugs.ruby-lang.org

こいつの再現手順を調べようとありゃこりゃやってた。

ruby 3.3.0 (2023-12-25 revision 5124f9ac75) +YJIT [x86_64-linux-musl]

Rails 7.1.3.2

まずはこの環境を準備するところから。

Alpine Linux の環境構築

ラップトップは Ubuntu 22.04 LTS なんで仮想環境を準備することにした。多分何度も ruby をビルドしたり rails をガチャガチャさわりそうな気がするので、コンテナではなくホスト型の仮想環境を用意することにした。

wiki.alpinelinux.org

wiki.alpinelinux.org

wiki.alpinelinux.org

setup-alpine 内の setup-disk でデフォルトの none ではなくちゃんと sda を指定あげればインストールできる。ありがとう、znz

あと再起動後は光学ディスクに指定している iso をちゃんと取り出しておくこと。セカンダリに設定しているのに何故か iso から起動するので diskless になっている気持ちになる。

VirtualBox のターミナルでは色々めんどいのでホストから ssh ログインできるようにした。あらかじめ VirtualBox はコピペできる設定にしておいた方がいい。公開鍵を手打ちで入力してやったぜ(一発でログインできた俺すげー)。盗まれることもないだろうけど鍵は ed25519 で作っておいた。

ruby をビルドするための準備

色々と勝手が Ubuntu と違うので戸惑ったりした。

  • apt -> apk
  • sudo -> doas

とりあえずこれだけ抑えとけば後はなんとかなる。

$ doas apk add build-base ruby-dev sqlite-dev nodejs yarn
$ doas apk add linux-headers libffi-dev zlib-dev openssl-dev yaml-dev gdbm-dev readline-dev autoconf rust

この辺をインストールしておけば YJIT を有効にした ruby はビルドできる。

ruby のビルド

3.3.0 の tarballwget で入手して展開し、この通りにやればいい。

…のだが、make -j は俺の環境だと

gcc: fatal error: Killed signal terminated program cc1
compilation terminated.
make: *** [Makefile:448: hash.o] Error 1
make: *** Waiting for unfinished jobs....

とエラーになった。多分仮想環境のリソース不足が原因だと思われ。おとなしく make をしよう。

3.3.0 のビルド

building Rust YJIT (release mode)
warning: unused import: `condition::Condition`
  --> ./yjit/src/asm/arm64/arg/mod.rs:13:9
   |
13 | pub use condition::Condition;
   |         ^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

warning: unused import: `rb_yjit_fix_mul_fix as rb_fix_mul_fix`
   --> ./yjit/src/cruby.rs:188:9
    |
188 | pub use rb_yjit_fix_mul_fix as rb_fix_mul_fix;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: 2 warnings emitted

touch yjit/target/release/libyjit.a
partial linking yjit/target/release/libyjit.a into yjit/target/release/libyjit.o
assembling coroutine/amd64/Context.S

なんか警告が出る。YJIT だし Rust だしでどうしたものか。

3.3.1 のビルド

気になったので 3.3.1 の tarball を wget してどうようにビルドしてみた。

regexec.c: In function 'match_at':
regexec.c:2598:59: warning: 'stkp' may be used uninitialized [-Wmaybe-uninitialized]
 2598 |         if (*pbegin == OP_REPEAT_INC) stkp->u.repeat.count--;\
      |                                       ~~~~~~~~~~~~~~~~~~~~^~
regexec.c:3852:11: note: in expansion of macro 'CHECK_MATCH_CACHE'
 3852 |           CHECK_MATCH_CACHE;
      |           ^~~~~~~~~~~~~~~~~
regexec.c:2297:18: note: 'stkp' was declared here
 2297 |   OnigStackType *stkp; /* used as any purpose. */
      |                  ^~~~
At top level:
cc1: note: unrecognized command-line option '-Wno-self-assign' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-parentheses-equality' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-constant-logical-operand' may have been intended to silence earlier diagnostics
building Rust YJIT (release mode)
warning: unused import: `condition::Condition`
  --> ./yjit/src/asm/arm64/arg/mod.rs:13:9
   |
13 | pub use condition::Condition;
   |         ^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

warning: unused import: `rb_yjit_fix_mul_fix as rb_fix_mul_fix`
   --> ./yjit/src/cruby.rs:188:9
    |
188 | pub use rb_yjit_fix_mul_fix as rb_fix_mul_fix;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: 2 warnings emitted

touch yjit/target/release/libyjit.a
partial linking yjit/target/release/libyjit.a into yjit/target/release/libyjit.o
assembling coroutine/amd64/Context.S
raddrinfo.c: In function 'rb_getnameinfo':
raddrinfo.c:753:11: warning: 'gni_errno' may be used uninitialized [-Wmaybe-uninitialized]
  753 |     errno = gni_errno;
raddrinfo.c:703:14: note: 'gni_errno' was declared here
  703 |     int err, gni_errno;
      |              ^~~~~~~~~
In function 'rb_getaddrinfo',
    inlined from 'rsock_getaddrinfo' at raddrinfo.c:962:21:
raddrinfo.c:534:11: warning: 'gai_errno' may be used uninitialized [-Wmaybe-uninitialized]
  534 |     errno = gai_errno;
raddrinfo.c: In function 'rsock_getaddrinfo':
raddrinfo.c:484:14: note: 'gai_errno' was declared here
  484 |     int err, gai_errno;
      |              ^~~~~~~~~
At top level:
cc1: note: unrecognized command-line option '-Wno-self-assign' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-parentheses-equality' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-constant-logical-operand' may have been intended to silence earlier diagnostics

3.3.0 より警告が出てた。

master のビルド

ここまで来ると master も気になるので 68b6fe70484b1fed2767fc9b838a487aa47d3560 までを pull ってきてビルド。

error.c: In function 'rb_enc_compile_warn':
error.c:410:9: warning: function 'rb_enc_compile_warn' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
  410 |         with_warn_vsprintf(enc, file, line, fmt) {
      |         ^~~~~~~~~~~~~~~~~~
error.c: In function 'rb_enc_compile_warning':
error.c:432:9: warning: function 'rb_enc_compile_warning' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
  432 |         with_warn_vsprintf(enc, file, line, fmt) {
      |         ^~~~~~~~~~~~~~~~~~
At top level:
cc1: note: unrecognized command-line option '-Wno-self-assign' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-parentheses-equality' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-constant-logical-operand' may have been intended to silence earlier diagnostics

まさかのここは Ubuntu と同じ警告だとは。もしかしたら Ubuntu でも 3.3.0 や 3.3.1 をビルドしたら同じ警告が出るのかも。また別の日に確かめてみよう。