Compile
Scala CLI compiles your code with its compile
command:
object Hello {
def main(args: Array[String]): Unit =
println("Hello")
}
scala-cli compile Hello.scala
Note that most Scala CLI commands automatically compile your code, if necessary.
The compile
command is useful if you want to check that your code compiles
(or to see the compilation warnings, if any occur) without running it or packaging it.
The most common compile
options are shown below.
For a full list of options, run scala-cli compile --help
, or check the options linked in the
reference documentation.
Test scope
--test
makes scala-cli
compile main and test scopes:
scala-cli compile --test Hello.scala
Watch mode
--watch
makes scala-cli
watch your code for changes, and re-compiles it upon any change:
scala-cli compile --watch Hello.scala
# Compiling project-cef76d561e (1 Scala source)
# Compiled 'project-cef76d561e'
# Watching sources, press Ctrl+C to exit.
# Compiling project-cef76d561e (1 Scala source)
# Compiled 'project-cef76d561e'
# Watching sources, press Ctrl+C to exit.
Scala version
Scala CLI uses the latest stable version of Scala which was tested in scala-cli
(see our list of Supported Scala Versions). You can specify the Scala version you'd like to use with --scala
:
scala-cli compile --scala 2.13.6 Hello.scala
scala-cli
works with all major 2.12.x
, 2.13.x
, and 3.x
Scala versions.
--scala
also accepts "short" Scala versions, such as 2.12
, 2
, or 3
. In this
case, it picks the highest corresponding stable Scala version:
scala-cli compile --scala 2.12 Hello.scala
scala-cli compile --scala 2 Hello.scala
scala-cli compile --scala 3 Hello.scala
Scala Nightlies
The nightly builds of Scala compiler are unstable ones which are published on a nightly basis.
To use the latest Scala 2 and Scala 3 nightly builds, pass 2.nightly
and 3.nightly
, respectively.
You can also request the last 2.12.nightly
and 2.13.nightly
versions. 2.13.nightly
is the same as 2.nightly
.
Moreover, passing the 3.{sub binary number}.nightly
format, such as 3.0.nightly
or 3.1.nightly
is accepted, too.
Scala CLI takes care of fetching the nightly builds of Scala 2 and Scala 3 from different repositories, without you having to pass their addresses as input after the --repo
flag.
For compiling with the latest Scala 2 nightly build:
scala-cli Hello.scala -S 2.nightly
For compiling with the latest Scala 3 nightly build:
scala-cli Hello.scala -S 3.nightly
For compiling with an specific nightly build, you have the full version for:
scala-cli Hello.scala -S 2.13.9-bin-4505094
For setting this inside scala files, use using
directives:
//> using scala "2.nightly"
//> using scala "3.nightly"
//> using scala "2.13.9-bin-4505094"
Dependencies
You can add dependencies on the command-line with --dependency
:
scala-cli compile Hello.scala \
--dependency org.scala-lang.modules::scala-parallel-collections:1.0.4
Note that --dependency
is only meant as a convenience. You should favor
adding dependencies in the source files themselves via using
directives.
You can also add simple JAR files — those that don’t have transitive dependencies — as dependencies, with --jar
:
scala-cli compile Hello.scala --jar /path/to/library.jar
See the Dependency management guide for more details.
Scala compiler options
Most Scala compiler options can be passed as-is to scala-cli
:
scala-cli compile Hello.scala -Xlint:infer-any
# Compiling project (1 Scala source)
# [warn] ./Hello.scala:2:11: a type was inferred to be `Any`; this may indicate a programming error.
# [warn] val l = List("a", true, 2, new Object)
# [warn] ^
# Compiled project
All scala-cli
options that start with:
-g
-language
-opt
-P
-target
-V
-W
-X
-Y
are assumed to be Scala compiler options.
Scala compiler options can also be passed with -O
:
scala-cli compile Hello.scala -O -deprecation -O -Xlint:infer-any
# [warn] ./Hello.scala:3:7: method x in class Some is deprecated (since 2.12.0): Use .value instead.
# [warn] opt.x
# [warn] ^
-O
accepts both options with the prefixes shown above, and those without such a prefix.
Scala compiler help
You can also view the Scala compiler help for a particular Scala version with --scalac-help
, which is an alias for -O -help
.
scala-cli -S 2.13.8 --scalac-help
# Usage: scalac <options> <source files>
#
# Standard options:
# -Dproperty=value Pass -Dproperty=value directly to the runtime system.
# -J<flag> Pass <flag> directly to the runtime system.
# -P:<plugin>:<opt> Pass an option to a plugin
# -V Print a synopsis of verbose options. [false]
# -W Print a synopsis of warning options. [false]
# -Werror Fail the compilation if there are any warnings. [false]
# -X Print a synopsis of advanced options. [false]
# -Y Print a synopsis of private options. [false]
# -bootclasspath <path> Override location of bootstrap class files.
# -classpath <path> Specify where to find user class files.
# -d <directory|jar> destination for generated classfiles.
# -dependencyfile <file> Set dependency tracking file.
# -deprecation Emit warning and location for usages of deprecated APIs. See also -Wconf. [false]
# -encoding <encoding> Specify character encoding used by source files.
# -explaintypes Explain type errors in more detail. [false]
# -extdirs <path> Override location of installed extensions.
# -feature Emit warning and location for usages of features that should be imported explicitly. See also -Wconf. [false]
# -g:<level> Set level of generated debugging info. (none,source,line,[vars],notailcalls)
# -help Print a synopsis of standard options [false]
# -javabootclasspath <path> Override java boot classpath.
# -javaextdirs <path> Override java extdirs classpath.
# -language:<features> Enable or disable language features
# -no-specialization Ignore @specialize annotations. [false]
# -nobootcp Do not use the boot classpath for the scala jars. [false]
# -nowarn Generate no warnings. [false]
# -opt:<optimizations> Enable optimizations, `help` for details.
# -opt-inline-from:<patterns> Patterns for classfile names from which to allow inlining, `help` for details.
# -opt-warnings:<warnings> Enable optimizer warnings, `help` for details.
# -print Print program with Scala-specific features removed. [false]
# -release <release> Compile for a specific version of the Java platform. Supported targets: 6, 7, 8, 9
# -rootdir <path> The absolute path of the project root directory, usually the git/scm checkout. Used by -Wconf.
# -sourcepath <path> Specify location(s) of source files.
# -target:<target> Target platform for object files. ([8],9,10,11,12,13,14,15,16,17,18)
# -toolcp <path> Add to the runner classpath.
# -unchecked Enable additional warnings where generated code depends on assumptions. See also -Wconf. [false]
# -uniqid Uniquely tag all identifiers in debugging output. [false]
# -usejavacp Utilize the java.class.path in classpath resolution. [false]
# -usemanifestcp Utilize the manifest in classpath resolution. [false]
# -verbose Output messages about what the compiler is doing. [false]
# -version Print product version and exit. [false]
# @<file> A text file containing compiler arguments (options and source files) [false]
#
# Deprecated settings:
# -optimize Enables optimizations. [false]
# deprecated: Since 2.12, enables -opt:l:inline -opt-inline-from:**. See -opt:help.
Other scalac print help options (like -X
, -Xshow-phases
, -Vphases
, etc.) are supported as well.
scala-cli -S 2.12.16 -Xshow-phases
#
# phase name id description
# ---------- -- -----------
# parser 1 parse source into ASTs, perform simple desugaring
# namer 2 resolve names, attach symbols to named trees
#packageobjects 3 load package objects
# typer 4 the meat and potatoes: type the trees
# patmat 5 translate match expressions
#superaccessors 6 add super accessors in traits and nested classes
# extmethods 7 add extension methods for inline classes
# pickler 8 serialize symbol tables
# refchecks 9 reference/override checking, translate nested objects
# uncurry 10 uncurry, translate function values to anonymous classes
# fields 11 synthesize accessors and fields, add bitmaps for lazy vals
# tailcalls 12 replace tail calls by jumps
# specialize 13 @specialized-driven class and method specialization
# explicitouter 14 this refs to outer pointers
# erasure 15 erase types, add interfaces for traits
# posterasure 16 clean up erased inline classes
# lambdalift 17 move nested functions to top level
# constructors 18 move field definitions into constructors
# flatten 19 eliminate inner classes
# mixin 20 mixin composition
# cleanup 21 platform-specific cleanups, generate reflective calls
# delambdafy 22 remove lambdas
# jvm 23 generate JVM bytecode
# terminal 24 the last phase during a compilation run
Scala compiler plugins
Use --compiler-plugin
to add compiler plugin dependencies:
scala-cli compile Hello.scala --compiler-plugin org.typelevel:::kind-projector:0.13.2 --scala 2.12.14
Printing a class path
--print-class-path
makes scala-cli compile
print a class path:
scala-cli compile --print-class-path Hello.scala
# /work/.scala/project-cef76d561e/classes:~/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.14/scala-library-2.12.14.jar:~/Library/Caches/ScalaCli/local-repo/0.1.0/org.virtuslab.scala-cli/runner_2.12/0.0.1-SNAPSHOT/jars/runner_2.12.jar:~/Library/Caches/ScalaCli/local-repo/0.1.0/org.virtuslab.scala-cli/stubs/0.0.1-SNAPSHOT/jars/stubs.jar
This is handy when working with other tools.
For example, you can pass this class path to java -cp
:
java -cp "$(scala-cli compile --print-class-path Hello.scala)" Hello
# Hello
Note that you should favor the run
command to run your code, rather than running java -cp
.
The class path obtained this way is only meant for scenarios where scala-cli
doesn't offer a more convenient option.
JVM options
--javac-opt
lets you add javac
options which will be passed when compiling sources.
scala-cli Hello.scala --javac-opt source --javac-opt 1.8 --javac-opt target --javac-opt 1.8
You can also add javac options with the using directive //> using javacOpt
:
//> using javacOpt "source", "1.8", "target", "1.8"