I'm trying to compile Scala files programmatically by using an instance of Global.Run
:
val settings = new Settings
val reporter = new ConsoleReporter(settings)
val compiler = new Global(settings, reporter)
val run = new compiler.Run // MissingRequirementError
run compile List(path)
Unfortunately I get a MissingRequirementError
saying:
object scala.runtime in compiler mirror not found
So my question is how can I compile a file programmatically by using the Run
class, or what am I doing wrong here?
I tried to figure out whether I could change the settings
in order to get it work. Actually I need a list of classes that are in the Scala file at path
, not necessarily a fully runnable output. It would therefore be fine if symbols remained unresolved (if I could run a subset of the compiler phases).
I also at Writing Scala Compiler Plugins, but if I can run it by instanciating a Compiler Run object, I'd prefer this solution. I also stumbled across Is the Scala compiler reentrant? (similar code, different question), which makes me think it might work the way I'm thinking of.
Edit 1: Added Scala JARs to the toolcp
(just sample code with absolute path!)
According to a comment I adapted scalac.bat
's classpath population script to my Scala code:
// scalac.bat
// if "%_TOOL_CLASSPATH%"=="" (
// for %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f"
// for /d %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f"
// )
new File("C:\\Program Files\\scala\\lib").listFiles.foreach(f => {
settings.classpath.append(f.getAbsolutePath)
settings.toolcp.append(f.getAbsolutePath)
})
I got it running, by using bootclasspath
instead of toolcp
(thanks to pedrofurla's hint):
val settings = new Settings
new File("C:\\Program Files\\scala\\lib").listFiles.foreach(f => {
settings.classpath.append(f.getAbsolutePath)
settings.bootclasspath.append(f.getAbsolutePath)
})
private val reporter = new ConsoleReporter(settings)
private val compiler = new Global(settings, reporter)
val run = new compiler.Run
run compile List(path)
The compiler attempts to compile the files now. However, this seems not to be exactly what scalac.bat
does. It starts it with -cp
, which is the normal classpath, whereas bootclasspath
is passed with -bootclasspath
on the console, as visible in StandardScalaSettings
trait:
val bootclasspath = PathSetting ("-bootclasspath", "Override location of bootstrap class files.", Defaults.scalaBootClassPath)