いけむランド

はてダからやってきました

Rust on cygwin を触ってみた

rust を cygwin 上で動かしたり、cygwin binary を吐かせたりするように頑張っているリポジトリがある。

github.com

ML で今年の夏頃にその話が流れていた。

cygwin.com

最近はちょっと進捗がなさそうだけど、リリースは本家に追従されている模様。

github.com

まずはざっと最新をダウンロードして、展開。

$ cd /tmp
$ wget https://github.com/jeremyd2019/cygwin-rust-bootstrap/releases/download/rust-1.91.0-cygwin/rust-1.91.0-x86_64-pc-cygwin.tar.xz
$ cd /opt
$ tar xf /tmp/rust-1.91.0-x86_64-pc-cygwin.tar.xz

次に公式からコピペで main.rs を作成する。

doc.rust-jp.rs

$ mkdir /tmp/rust
$ cd /tmp/rust
$ vi main.rs
$ /opt/rust-1.91.0-x86_64-pc-cygwin/rustc/bin/rustc.exe main.rs
error[E0463]: can't find crate for `std`
  |
  = note: the `x86_64-pc-cygwin` target may not be installed
  = help: consider downloading the target with `rustup target add x86_64-pc-cygwin`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0463`.

$  /opt/rust-1.91.0-x86_64-pc-cygwin/rustc/bin/rustc.exe --print sysroot
/opt/rust-1.91.0-x86_64-pc-cygwin/rustc

std が sysroot 配下に見当たらないことが問題っぽい。公式ドキュメント (と AI による説明) によると ${sysroot}/lib/rustlib/${target}/lib/libstd-*.rlib を探しに行くらしい。

rustc-dev-guide.rust-lang.org

std 自体は別ディレクトリにあるため、シンボリックリンクでごまかしてみた。

$ ls -1 /opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/*std*
/opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/librustc_std_workspace_alloc-32594e9be0f8a4e3.rlib
/opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/librustc_std_workspace_core-dde574a0af99b6b5.rlib
/opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/librustc_std_workspace_std-2b26e5b8a5c6eead.rlib
/opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/libstd-3585836e727cff80.dll.a
/opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/libstd-3585836e727cff80.rlib
/opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/libstd_detect-d0b69e5fae8b8f7e.rlib
/opt/rust-1.91.0-x86_64-pc-cygwin/rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib/std-3585836e727cff80.dll

$ cd /opt/rust-1.91.0-x86_64-pc-cygwin/rustc/lib/rustlib/x86_64-pc-cygwin/
$ ln -fs ../../../../rust-std-x86_64-pc-cygwin/lib/rustlib/x86_64-pc-cygwin/lib lib

今度はビルドに成功した。

$ cd /tmp/rust
$ /opt/rust-1.91.0-x86_64-pc-cygwin/rustc/bin/rustc.exe -v main.rs
$ ./main.exe
Hello, world!

きちんと Cygwin DLL への依存がある。

$ ldd ./main.exe | grep /usr/bin/cyg
        cygwin1.dll => /usr/bin/cygwin1.dll (0x7ffd8f2c0000)
        cyggcc_s-seh-1.dll => /usr/bin/cyggcc_s-seh-1.dll (0x50caa0000)

バイナリは結構でかい。strip してもそこそこある。

$ ls -Gg main.exe
-rwxr-xr-x 1 1217434 Dec 29 12:51 main.exe
$ strip main.exe
$ ls -Gg main.exe
-rwxr-xr-x 1 860160 Dec 29 12:56 main.exe

さすがに RubyJITコンパイルできるかがまだわからないけど、なかなか面白いことにはなりそう。