はじめに
とりあえず必要なものを順番にインストールしていますが、plantuml をインストールしようとして、依存関係の librsvg のインストールでハマりました。librsvg の build で rust を使っているためです。
rust は現状で brew ではインストールできませんが、1.49-beta は Apple Sillicon 対応になっています。Ruby の rbenv と同様に、Rust も Cargo でフォルダごとに管理したいので、1.49-beta を個人でインストールすることにしました。
Rustup でのインストール
Rust のインストールは rustup.rs を対話的に実施するのが通常です。 今回は、beta を支持する必要がありますが、bootstrap.sh から非対話でインストールしたいため、少し工夫します。 調べてみると、rustup を非対話的環境でインストールする方法 - Qiitaという記事を見つけました。通常、
curl https://sh.rustup.rs -sSf | sh
とするところですが、rustup.rs に引数を与えたいため、以下のように sh の引数を設定します。-s -- の後ろの部分が rustup.rs への引数になるそうです。
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain beta -y
ということで、冪等性を考えて以下のようなスクリプトを .bootstrap.sh に追加しました。ここまでやって、./bootstrap.sh で rust-1.49-beta が $HOME/.cargo/bin にインストールされました。試しに PATH に ~/.cargo/bin にパスを通すと rustc が動作しました。
# Install Rust 1.49-beta using rustup.rs if [ ! -d "$HOME/.cargo" ]; then echo "Installing rust-beta ..." curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain beta -y fi
librsvg のコンパイルエラー
これで librsvg がコンパイルできるかと思いましたができませんでした。調べてみると、Homebrew の superenv - Qiitaというものが設定されているため、PATH に ~/.cargo/bin を通していても無視するようです。ここで、--env=std
をつけると設定した superenv を無視して、設定されたパスを使ってくれるということでした。
今度こそと試してみましたが、今度は error: no override and no default toolchain set
というメッセージでコンパイルが止まってしまいました。brew のコンパイルでは sandbox-exec をする手前、個人のフォルダに入っている toolchain を見つけることができないのではないかと考えました。
rust Formula のリバースエンジニアリング
こうなると、rust の野良 brew を作るということになるのですが、rust-arm64.rb を作ろうとしても、beta 版の tarball のパスを調べることは困難でした。そこで、すでに .rustup の下にインストールされているファイルを rust Formula と同じ形で配置してしまうことを考えました。作戦が決まればリバースエンジニアリング開始です。
まずは Rosetta2 の brew で Intel 版の 1.48 stable をインストールしてみます。Intel 版なので、/usr/local にインストールされています。
hkob@hM1Air ~> arch --arch x86_64 brew_x86 install rust ==> Installing dependencies for rust: libssh2 and pkg-config ==> Installing rust dependency: libssh2 ==> Pouring libssh2-1.9.0_1.big_sur.bottle.tar.gz 🍺 /usr/local/Cellar/libssh2/1.9.0_1: 184 files, 969.9KB ==> Installing rust dependency: pkg-config ==> Pouring pkg-config-0.29.2_3.big_sur.bottle.tar.gz 🍺 /usr/local/Cellar/pkg-config/0.29.2_3: 11 files, 656.6KB ==> Installing rust ==> Pouring rust-1.48.0.big_sur.bottle.tar.gz 🍺 /usr/local/Cellar/rust/1.48.0: 14,251 files, 558.0MB
ここで、brew list を使って、rust で何がインストールされているかを確認します。
hkob@hM1Air ~> arch --arch x86_64 brew_x86 list rust /usr/local/Cellar/rust/1.48.0/.crates.toml /usr/local/Cellar/rust/1.48.0/.crates2.json /usr/local/Cellar/rust/1.48.0/bin/cargo /usr/local/Cellar/rust/1.48.0/bin/rust-gdb /usr/local/Cellar/rust/1.48.0/bin/rust-gdbgui /usr/local/Cellar/rust/1.48.0/bin/rust-lldb /usr/local/Cellar/rust/1.48.0/bin/rustc /usr/local/Cellar/rust/1.48.0/bin/rustdoc /usr/local/Cellar/rust/1.48.0/etc/bash_completion.d/cargo.bashcomp.sh /usr/local/Cellar/rust/1.48.0/lib/libchalk_derive-97d218325ef82204.dylib /usr/local/Cellar/rust/1.48.0/lib/librustc_driver-3640549726d24237.dylib /usr/local/Cellar/rust/1.48.0/lib/librustc_macros-3d08af3a460c63ca.dylib /usr/local/Cellar/rust/1.48.0/lib/libstd-93fc378b6b7db88c.dylib /usr/local/Cellar/rust/1.48.0/lib/libtest-7ec4a3c03eb88004.dylib /usr/local/Cellar/rust/1.48.0/lib/libtracing_attributes-159b2b2525b4554d.dylib /usr/local/Cellar/rust/1.48.0/lib/rustlib/ (38 files) /usr/local/Cellar/rust/1.48.0/share/doc/ (14157 files) /usr/local/Cellar/rust/1.48.0/share/man/ (34 files) /usr/local/Cellar/rust/1.48.0/share/zsh/site-functions/_cargo
これらのファイルが /usr/local のどこにリンクが貼られているかを brew link -v で確認します。link するために、一度 brew unlink して、再度リンクを verbose モードで実施しました。
hkob@hM1Air ~> arch --arch x86_64 brew_x86 link -v rust Linking /usr/local/Cellar/rust/1.48.0... ln -s ../../Cellar/rust/1.48.0/etc/bash_completion.d/cargo.bashcomp.sh cargo.bashcomp.sh ln -s ../Cellar/rust/1.48.0/bin/cargo cargo ln -s ../Cellar/rust/1.48.0/bin/rust-gdb rust-gdb ln -s ../Cellar/rust/1.48.0/bin/rust-gdbgui rust-gdbgui ln -s ../Cellar/rust/1.48.0/bin/rust-lldb rust-lldb ln -s ../Cellar/rust/1.48.0/bin/rustc rustc ln -s ../Cellar/rust/1.48.0/bin/rustdoc rustdoc ln -s ../../Cellar/rust/1.48.0/share/doc/rust rust ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-bench.1 cargo-bench.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-build.1 cargo-build.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-check.1 cargo-check.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-clean.1 cargo-clean.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-doc.1 cargo-doc.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-fetch.1 cargo-fetch.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-fix.1 cargo-fix.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-generate-lockfile.1 cargo-generate-lockfile.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-help.1 cargo-help.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-init.1 cargo-init.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-install.1 cargo-install.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-locate-project.1 cargo-locate-project.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-login.1 cargo-login.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-metadata.1 cargo-metadata.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-new.1 cargo-new.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-owner.1 cargo-owner.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-package.1 cargo-package.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-pkgid.1 cargo-pkgid.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-publish.1 cargo-publish.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-run.1 cargo-run.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-rustc.1 cargo-rustc.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-rustdoc.1 cargo-rustdoc.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-search.1 cargo-search.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-test.1 cargo-test.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-tree.1 cargo-tree.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-uninstall.1 cargo-uninstall.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-update.1 cargo-update.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-vendor.1 cargo-vendor.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-verify-project.1 cargo-verify-project.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-version.1 cargo-version.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo-yank.1 cargo-yank.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/cargo.1 cargo.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/rustc.1 rustc.1 ln -s ../../../Cellar/rust/1.48.0/share/man/man1/rustdoc.1 rustdoc.1 ln -s ../../../Cellar/rust/1.48.0/share/zsh/site-functions/_cargo _cargo ln -s ../Cellar/rust/1.48.0/lib/libchalk_derive-97d218325ef82204.dylib libchalk_derive-97d218325ef82204.dylib ln -s ../Cellar/rust/1.48.0/lib/librustc_driver-3640549726d24237.dylib librustc_driver-3640549726d24237.dylib ln -s ../Cellar/rust/1.48.0/lib/librustc_macros-3d08af3a460c63ca.dylib librustc_macros-3d08af3a460c63ca.dylib ln -s ../Cellar/rust/1.48.0/lib/libstd-93fc378b6b7db88c.dylib libstd-93fc378b6b7db88c.dylib ln -s ../Cellar/rust/1.48.0/lib/libtest-7ec4a3c03eb88004.dylib libtest-7ec4a3c03eb88004.dylib ln -s ../Cellar/rust/1.48.0/lib/libtracing_attributes-159b2b2525b4554d.dylib libtracing_attributes-159b2b2525b4554d.dylib ln -s ../Cellar/rust/1.48.0/lib/rustlib rustlib 50 symlinks created
確認できたので、rust および関連でインストールされた pkg-config, libssh2 を削除します。
arch --arch x86_64 brew_x86 uninstall rust arch --arch x86_64 brew_x86 uninstall pkg-config libssh2
rust beta のフォルダ構成の確認
ここで、$HOME/.rustup/toolchains/beta-aarch64-apple-darwin のフォルダ構成と比較します。
hkob@hM1Air ~/.r/t/beta-aarch64-apple-darwin> find . -type f -print ./bin/rustdoc ./bin/cargo ./bin/clippy-driver ./bin/rust-gdbgui ./bin/rust-lldb ./bin/cargo-clippy ./bin/rustc ./bin/cargo-fmt ./bin/rustfmt ./bin/rust-gdb ./etc/bash_completion.d/cargo ./lib/rustlib/manifest-rust-std-aarch64-apple-darwin ./lib/rustlib/manifest-clippy-preview-aarch64-apple-darwin ./lib/rustlib/aarch64-apple-darwin/bin/rust-lld ./lib/rustlib/aarch64-apple-darwin/lib/libprofiler_builtins-8cd5d7a49915f347.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libgetopts-5938f1e18d91ac9a.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libunwind-5c4568ce399a1ac6.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libstd-fb92146976358ada.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libgimli-8808255652f9fb1e.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libpanic_unwind-1a980f3f9f4d2496.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libcompiler_builtins-599297c08cf4e309.rlib ./lib/rustlib/aarch64-apple-darwin/lib/liblibc-6277ce3c4f9565ca.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libtest-57a3dd85bf3a66f3.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libproc_macro-5a5e33eb413ba2a3.rlib ./lib/rustlib/aarch64-apple-darwin/lib/librustc_std_workspace_core-d786e5a700f40e71.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libcfg_if-6e5804dfdd49bfe7.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libstd-fb92146976358ada.dylib ./lib/rustlib/aarch64-apple-darwin/lib/liballoc-4e88f8eccf13cb06.rlib ./lib/rustlib/aarch64-apple-darwin/lib/librustc_std_workspace_alloc-e6361ce0a3a7e57a.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libtest-57a3dd85bf3a66f3.dylib ./lib/rustlib/aarch64-apple-darwin/lib/libminiz_oxide-23db372741135ce1.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libterm-79c0eec85296adf4.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libobject-aef43015d2e37ee0.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libaddr2line-9c0215ae58a8f126.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libadler-a1c85ab61273c673.rlib ./lib/rustlib/aarch64-apple-darwin/lib/librustc_demangle-257f812d85eafca4.rlib ./lib/rustlib/aarch64-apple-darwin/lib/librustc_std_workspace_std-a298a9fa2b4358aa.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libhashbrown-87a6a4e1ef91bbdf.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libunicode_width-d13da60bd092a62c.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libpanic_abort-2ff1715a996a2224.rlib ./lib/rustlib/aarch64-apple-darwin/lib/libcore-f357a5f6f2a76d4d.rlib ./lib/rustlib/etc/gdb_providers.py ./lib/rustlib/etc/lldb_commands ./lib/rustlib/etc/gdb_load_rust_pretty_printers.py ./lib/rustlib/etc/rust_types.py ./lib/rustlib/etc/lldb_lookup.py ./lib/rustlib/etc/lldb_providers.py ./lib/rustlib/etc/gdb_lookup.py ./lib/rustlib/multirust-channel-manifest.toml ./lib/rustlib/rust-installer-version ./lib/rustlib/manifest-rustc-aarch64-apple-darwin ./lib/rustlib/multirust-config.toml ./lib/rustlib/components ./lib/rustlib/manifest-rustfmt-preview-aarch64-apple-darwin ./lib/rustlib/manifest-cargo-aarch64-apple-darwin ./lib/libchalk_derive-b6546ec3dd9d440a.dylib ./lib/libtracing_attributes-88dfc0f8a9ccf25a.dylib ./lib/libstd-fb92146976358ada.dylib ./lib/libtest-57a3dd85bf3a66f3.dylib ./lib/librustc_driver-cba1fe2bb3f1909c.dylib ./lib/librustc_macros-4215e8aab5ed3aeb.dylib ./share/man/man1/cargo-doc.1 ./share/man/man1/cargo-init.1 ./share/man/man1/cargo-build.1 ./share/man/man1/cargo-clean.1 ./share/man/man1/cargo.1 ./share/man/man1/rustdoc.1 ./share/man/man1/rustc.1 ./share/man/man1/cargo-pkgid.1 ./share/man/man1/cargo-new.1 ./share/man/man1/cargo-rustc.1 ./share/man/man1/cargo-metadata.1 ./share/man/man1/cargo-version.1 ./share/man/man1/cargo-install.1 ./share/man/man1/cargo-uninstall.1 ./share/man/man1/cargo-rustdoc.1 ./share/man/man1/cargo-bench.1 ./share/man/man1/cargo-verify-project.1 ./share/man/man1/cargo-run.1 ./share/man/man1/cargo-test.1 ./share/man/man1/cargo-generate-lockfile.1 ./share/man/man1/cargo-vendor.1 ./share/man/man1/cargo-check.1 ./share/man/man1/cargo-search.1 ./share/man/man1/cargo-fetch.1 ./share/man/man1/cargo-update.1 ./share/man/man1/cargo-tree.1 ./share/man/man1/cargo-fix.1 ./share/man/man1/cargo-login.1 ./share/man/man1/cargo-yank.1 ./share/man/man1/cargo-publish.1 ./share/man/man1/cargo-locate-project.1 ./share/man/man1/cargo-help.1 ./share/man/man1/cargo-owner.1 ./share/man/man1/cargo-package.1 ./share/doc/cargo/LICENSE-THIRD-PARTY ./share/doc/cargo/LICENSE-APACHE ./share/doc/cargo/README.md ./share/doc/cargo/LICENSE-MIT ./share/doc/rust/LICENSE-APACHE ./share/doc/rust/README.md ./share/doc/rust/COPYRIGHT ./share/doc/rust/LICENSE-MIT ./share/doc/clippy/LICENSE-APACHE ./share/doc/clippy/README.md ./share/doc/clippy/LICENSE-MIT ./share/doc/rustfmt/LICENSE-APACHE ./share/doc/rustfmt/README.md ./share/doc/rustfmt/LICENSE-MIT ./share/zsh/site-functions/_cargo
ほぼ構成一緒ですね。これらを /opt/homebrew の中に同じような形でシンボリックリンクを貼ればいいはずです。
rust beta の /opt/homebrew 配下へのインストール
先程のインストール部分の後ろに /opt/homebrew へのシンボリックリンクを貼る処理を追加しました。実際にこれで ./bootstrap.sh を実行しました。このシンボリックリンクにより ~/.cargo/bin を PATH に追加しなくても、rustc が動作することを確認しました。
# Install Rust 1.49-beta using rustup.rs if [ ! -d "$HOME/.cargo" ]; then echo "Installing rust-beta ..." curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain beta -y LINK_FILES=$(cat <<FILE_END bin/rustdoc bin/cargo bin/clippy-driver bin/rust-gdbgui bin/rust-lldb bin/cargo-clippy bin/rustc bin/cargo-fmt bin/rustfmt bin/rust-gdb etc/bash_completion.d/cargo lib/rustlib lib/libchalk_derive-b6546ec3dd9d440a.dylib lib/libtracing_attributes-88dfc0f8a9ccf25a.dylib lib/libstd-fb92146976358ada.dylib lib/libtest-57a3dd85bf3a66f3.dylib lib/librustc_driver-cba1fe2bb3f1909c.dylib lib/librustc_macros-4215e8aab5ed3aeb.dylib share/man/man1/cargo-doc.1 share/man/man1/cargo-init.1 share/man/man1/cargo-build.1 share/man/man1/cargo-clean.1 share/man/man1/cargo.1 share/man/man1/rustdoc.1 share/man/man1/rustc.1 share/man/man1/cargo-pkgid.1 share/man/man1/cargo-new.1 share/man/man1/cargo-rustc.1 share/man/man1/cargo-metadata.1 share/man/man1/cargo-version.1 share/man/man1/cargo-install.1 share/man/man1/cargo-uninstall.1 share/man/man1/cargo-rustdoc.1 share/man/man1/cargo-bench.1 share/man/man1/cargo-verify-project.1 share/man/man1/cargo-run.1 share/man/man1/cargo-test.1 share/man/man1/cargo-generate-lockfile.1 share/man/man1/cargo-vendor.1 share/man/man1/cargo-check.1 share/man/man1/cargo-search.1 share/man/man1/cargo-fetch.1 share/man/man1/cargo-update.1 share/man/man1/cargo-tree.1 share/man/man1/cargo-fix.1 share/man/man1/cargo-login.1 share/man/man1/cargo-yank.1 share/man/man1/cargo-publish.1 share/man/man1/cargo-locate-project.1 share/man/man1/cargo-help.1 share/man/man1/cargo-owner.1 share/man/man1/cargo-package.1 share/doc/cargo share/doc/rust share/doc/clippy share/doc/rustfmt share/zsh/site-functions/_cargo FILE_END ) for file in $LINK_FILES do rm -rf /usr/local/$file ln -sf $HOME/.rustup/toolchains/beta-aarch64-apple-darwin/$file /opt/homebrew/$file done fi
plantuml までの道
ここまでできれば、あとは野良 brew を作ればいいだけです。以下の Formula を作成しました。 * librsvg-arm64: depends_on "rust" => :build を削除 * graphviz: depends_on "librsvg-arm64" に変更 * plantuml: depends_on "cask" => "zulu11-arm64" に変更。plantuml 内の java 呼び出し部を openjdk から zulu の /usr/bin/java に変更
今回は非常に大変でした。1日仕事になってしまいました。
前の記事: MacFuse および sshfs の断念 - M1 MacBook Air インストール覚書(20) - hkob’s blog