6
votes

I am using sourceGenerators in Compile to generate some Scala source files to target\scala-2.10\src_managed. When I run sbt compilethe sources are generated and compiled along with the regular code under src\main\scala.

But what if I want to generate the sources separately without compiling? What I am looking for is this flow:

  1. call a task to generate source code
  2. use the generated sources for IDE assistance in my regular sources
  3. compile everything

How can this be accomplished?

1
What exactly do you mean by make use of? Is this a question about IDE setup? Because you can of course cross reference from generated to unmanaged sources and the other way around... - Martin Ring
@I.K: yes I have read the posts but if you use sourceGenerators, I don't see how you can generate code without running sbt compile. I have now added a Generators.scala file in the project folder in my application. Then I have added a new task (makeGamedata) in my build.sbt which uses the Generators class to generate source code. So my development cycle is now: sbt makeGamedata > wrote code on src/main/scala that is using the generated source > sbt compile to compile everything. This works good. Now I need to figure out how to unit test code in the project folder .. - reikje
@Martin Ring: Martin, yes that works fine but they are always generated and compiled together. I would like to do the generation as an extra task, i.e. sbt generate to generate source code in src_managed > develop code that uses these source in src/main/scala > compile everything. - reikje
@reikje: I still don't understand what you mean by code that uses these sources? - Martin Ring

1 Answers

3
votes

Update

If I got you correct now, you want to be able to call the source generators seperately. For that you can simply define a custom task like this somewhere in your /build.sbt or /project/Project.scala file:

val generateSources = taskKey[List[File]]("generate sources")

generateSources <<= 
  (sourceGenerators in Compile) { _.join.map(_.flatten.toList) }

you can then call the generator manually from the sbt console like this:

> generateSources
[success] Total time: 0 s, completed 07.04.2014 13:42:41

Side Note: I would however reccomend to setup your IDE to generate the sources if the only thing you need them for is to get IDE support.


Old answer for future reference

You don't need to do anything special to use a generated class or object from a non-generated class or object.

In your /build.sbt or /project/Project.scala file you define the source generator:

sourceGenerators in Compile <+= sourceManaged in Compile map { dir =>
  val file = dir / "A.scala"
  IO.write(file, "class A(val name: String)")
  Seq(file)
}

Then you write some code which creates an instance of class A in/src/main/scala/B.scala:

object B extends App {
  val a = new A("It works")
  println(a.name)
}

If you compile this code from sbt, it will consider both generated and non-generated code at compilation:

> run
[info] Compiling 2 scala sources to <...>
[info] Running B
It works
[success] Total time: 0 s, completed 07.04.2014 13:15:47