4

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)
})
2
  • 2
    Added all jars to your class path? Check scalac and see how it setups the classpath of what is to be compiled. Commented Dec 3, 2012 at 14:55
  • @pedrofurla I had appended it to classpath, but not to toolcp yet. I added some code, but it does not help (same error). Edited the question. Thanks for reading and commenting! Commented Dec 3, 2012 at 15:51

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.