Scala-CLI でシングルバイナリを吐かせてみるテスト
ことの発端
ある日 Twitter で時間を溶かしているとこんな記事を見つけた。
Scala Nativeがいつのまにかシングルバイナリを吐けるようになっていた
いい感じに配布しやすい形で何か作れないかなぁとちょうど思っており、Scala 自体にも前々から興味はあったため、これに飛びついた、という次第。
環境構築
毎度毎度苦しむことでおなじみの環境構築。御多分にもれず今回も祝日の半日を飛ばすというポンコツっぷり。使用 OS は Windows です。
結論から書きます。最終的にシングルバイナリを吐けるようになるまでにやったことは以下です。やった順番通りに書きます。
それぞれ何のツールなのかはよくわかってない世の中にもっといい記事があると思いますので、譲ります。
それぞれ入れ方を順に説明します。
Scala-CLI のインストール
これはそんなに問題ないと思います。リンクを開いてすこし下ればわかりやすくボタンが置いてあるので、落とします。インストーラの指示に従います。
今回使いたい package 機能は、使う際 --power
オプションをつけなきゃいけないのですが、毎回付けるの面倒なので付けなくていいようにデフォルト設定を変えます。こちらの記事 を参考にしてます。
% scala-cli config power true
この時点で、おそらく以下のコマンドでバイナリ自体は吐けるようになってると思います。
% scala-cli package test.sc
test.sc
の中身はこんな感じ。一瞬で終了しちゃわないように、入力待ちを入れます。
println("Hello, Scala!")
scala.io.StdIn.readLine()
で、単独実行可能なシングルバイナリを吐くコマンドは
% scala-cli package test.sc --native
なのですが、この時点だとおそらくエラーがだらだら出てきます。私の場合、#include <stdio.h>
が見つからない、みたいなやつが大量に出てきました。
スタックトレースがログファイルに吐かれており、こんな感じでした。
scala.build.errors.ScalaNativeBuildError: Error compiling with Scala Native
scala.cli.commands.package0.Package$.buildNative$$anonfun$1(Package.scala:1091)
scala.build.EitherCps$Helper.apply(EitherCps.scala:19)
scala.cli.commands.package0.Package$.buildNative(Package.scala:1095)
scala.cli.commands.package0.Package$.doPackage$$anonfun$1(Package.scala:400)
scala.build.EitherCps$Helper.apply(EitherCps.scala:19)
scala.cli.commands.package0.Package$.doPackage(Package.scala:526)
scala.cli.commands.package0.Package$.runCommand(Package.scala:155)
scala.cli.commands.package0.Package$.runCommand(Package.scala:71)
scala.cli.commands.ScalaCommand.run(ScalaCommand.scala:376)
scala.cli.commands.ScalaCommand.run(ScalaCommand.scala:358)
caseapp.core.app.CaseApp.main(CaseApp.scala:157)
scala.cli.commands.ScalaCommand.main(ScalaCommand.scala:343)
caseapp.core.app.CommandsEntryPoint.main(CommandsEntryPoint.scala:166)
scala.cli.ScalaCliCommands.main(ScalaCliCommands.scala:125)
scala.cli.ScalaCli$.main0(ScalaCli.scala:286)
scala.cli.ScalaCli$.main(ScalaCli.scala:114)
scala.cli.ScalaCli.main(ScalaCli.scala)
なるほど、どうやら LLVM/sbt/clang/clang++ といったものが必要だと。というわけで入れていきます。
LLVM のインストール
ダウンロードページはこちら。
何種類かダウンロードする方法があるみたいですが、 私は GitHub からにしました。 バージョンはこれ以降なら動くんじゃないかなと思います(たぶん)。
インストーラが途中、パス通すかどうかみたいなのを聞いてきます。ラジオボタンで選択式なのですが、デフォが通さないになってますので、楽したい人は注意です。
sbt のインストール
ダウンロードページはこちら。
こちらも何種類かダウンロード方法があるようですが、
Install sbt with cs setup
こちらから実施しました。インストーラの指示に従って実行し、完了後に
scala -version
でちゃんとバージョンが表示されるか確かめて、終わりです。
Visual Studio のインストール
これに至ってはなんで必要なのかあんま理解してなかったり
こちらの記事 を参考に進めます。というか
Build Tools for Visual Studio 2022 インストール手順
をまんま実施するだけです。たすかる~。
おめあてのシングルバイナリを吐けることを確かめる
ここまで進めれば環境構築としては終わりのはずです。
% scala-cli package test.sc --native
を実行すると test.exe
ができると思いますので、これを実行して、期待通りの動作(文字が表示されて Enter 押したら消える)をするのを確認して完了になります。お疲れさまでした。
ここには書かなかったけど必要であろうこと
- JDK のインストール
- ゼロから構築する際には必要だと思います。私は元々入れててパスも通してました。
- ちなみに、私の環境の JDK のバージョンは 21 で、sbt の推奨バージョンではないですが、今のところ特に問題なく動いてます。
おわりに
普段から IDE におんぶにだっこなので、こういうの極端に弱くてダメですね。 反省はしてるし今後はやってかないといけないなぁと思ってはおりますが二度とやりたくないです。正直。
参考サイト
既に紹介したものも含めて、今回参考にした記事を挙げます。