Skip to the content.

Scala-CLI でシングルバイナリを吐かせてみるテスト

ことの発端

ある日 Twitter で時間を溶かしているとこんな記事を見つけた。

Scala Nativeがいつのまにかシングルバイナリを吐けるようになっていた

いい感じに配布しやすい形で何か作れないかなぁとちょうど思っており、Scala 自体にも前々から興味はあったため、これに飛びついた、という次第。

環境構築

毎度毎度苦しむことでおなじみの環境構築。御多分にもれず今回も祝日の半日を飛ばすというポンコツっぷり。使用 OS は Windows です。

結論から書きます。最終的にシングルバイナリを吐けるようになるまでにやったことは以下です。やった順番通りに書きます。

それぞれ何のツールなのかはよくわかってない世の中にもっといい記事があると思いますので、譲ります。

それぞれ入れ方を順に説明します。

Scala-CLI のインストール

これはそんなに問題ないと思います。リンクを開いてすこし下ればわかりやすくボタンが置いてあるので、落とします。インストーラの指示に従います。 image

今回使いたい 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 押したら消える)をするのを確認して完了になります。お疲れさまでした。

ここには書かなかったけど必要であろうこと

おわりに

普段から IDE におんぶにだっこなので、こういうの極端に弱くてダメですね。 反省はしてるし今後はやってかないといけないなぁと思ってはおりますが二度とやりたくないです。正直。

参考サイト

既に紹介したものも含めて、今回参考にした記事を挙げます。