scala-cli 기본 사용법
scala-cli는 Scala의 Command line interface로서 scala 3.5 부터는 기본 scala 실행시 scala-cli가 실행됩니다. coursier를 사용해서 scala-cli를 따로 설치할 수도 있으며 이것을 권장하고 있습니다.
기존의 scala repl과 달리 scala-cli는 repl로 사용할 수 있을 뿐 아니라 scala script 방식의 sc 파일도 지원해서 간단한 스크립트를 하나의 scala 파일로 작성할 수 있습니다. 예전에는 외부 패키지를 사용하는 경우 간단한 소스를 컴파일, 실행하기 위해서도 sbt나 mill과 같은 build tool을 써야 했지만 이제 scala 명령으로도 간단히 컴파일, 실행, 패키징까지 사용할 수 있게 되었습니다.
또한 scala 소스의 URL, gist, zip 파일도 지원하며 shell piping도 사용할 수 있습니다.
인자
--scala
: scala 버전을 지정할 수 있습니다--dependency
: 필요한 패키지를 지정할 수 있습니다. 개인적으로는 소스에서using dep
명령을 사용하는 것을 더 선호합니다-O
: scala 컴파일러 옵션을 지정합니다. 소스에서using option
으로 지정할 수도 있습니다--bloop-java-opt
: java 컴파일러 옵션을 지정합니다--javac-opt
: JVM 옵션을 지정합니다. 소스에서using javacOpt
를 사용할수 있습니다--java-opt
: 실행시 java 옵션을 지정합니다.using javaOpt
를 사용할 수 있습니다--js
: scala.js 어플리케이션을 컴파일하고 실행합니다.node
가 설치되어 있어야 합니다--native
: scala native 어필리케이션을 컴파일하고 실행합니다.
패키징
패키징 명령을 사용하기 위해서는 --power
옵션을 주어야 합니다.
- 기본 package 형식은 가벼운 실행 jar (lightweight launcher JAR) 파일을 생성합니다. java 명령어가 PATH에 지정되어 있기만하면 실행할 수 있습니다.
- library JAR :
--library
옵션을 주면 생성되며 class path를 가지는 JAR 파일이 만들어 집니다 - assembly JAR :
--assembly
옵션을 주면 바이트 코드와 필요 패키지를 혼합한 assembly JAR가 만들어지며 이는 크기가 크지만 아무것도 다운로드 받을 필요없이 실행시킬 수 있습니다. 기본으로는 바로 실행할 수 있는 형식이지만--preamble=false
옵션을 주면 java에서 실행시켜야 하는 JAR 파일이 만들어집니다 - docker image :
--docker
옵션을 주면 docker image를 만들어 줍니다.--docker-image-repository
옵션을 함께 사용해야 합니다.--docker-from
옵션으로 base docker image를 지정할 수 있습니다 - native image :
--native-image
옵션으로 graalVM native image를 만들 수 있습니다 - scala native 어플리케이션을 packaging하면 native 실행파일이 만들어집니다
- OS별 packages : 실험적 기능이며
--deb
,--rpm
,--pkg
,--msi
옵션으로 만들수 있고 각각 필요한 패키지들이 설치되어 있어야 합니다 - 이들 옵션은 소스 코드내에
using
명령어로 지정할 수도 있으며 자세한 것은 이곳을 참조하면 되겠습니다
publish
Maven 리포지토리나 GitHub 패키지로 publish하는 기능도 실험적으로 지원하고 있습니다.
Sample
10000번째 소수를 구하는 프로그램입니다. primes.sc로 저장하면 scala primes.sc
로 실행할 수 있습니다.
1
2
3
4
5
6
val primes: LazyList[Long] =
2L #::
LazyList.iterate(3L)(_ + 2).filter(odds =>
primes.takeWhile(p => p*p <= odds).forall(p => odds % p != 0))
println(s"10000번째 소수는 ${primes(9999)}입니다.")
실행파일로 packaging해 보겠습니다. 각각 기본 lightweight jar, fat jar (assembly), graal native image, scala native image, scala.js의 순서대로 packaing하는 명령입니다.
1
2
3
4
5
scala-cli --power package -o primes.lightweightjar primes.sc
scala-cli --power package --assembly -o primes.fatjar primes.sc
scala-cli --power package --native-image -o primes.graal primes.sc
scala-cli --power package --native -o primes.native primes.sc
scala-cli --power package --js -o primes.js primes.sc
다음은 결과 파일의 크기와 time
명령으로 3회 측정한 실행시간입니다.
name | size | time |
---|---|---|
lightweight | 172K | 0.34s |
fatjar | 6.8M | 0.24s |
graal | 13M | 0.06s |
native | 1.0M | 0.12s |
js | 133K | 0.16s |
예는 다른 패키지를 사용하지 않아 native나 js로 컴파일 가능했지만 java 패키지를 사용하는 경우에는 lightweight나 graal을 사용할 것 같습니다. 2025년 초 맥에서 실행한 결과입니다.