Buildr: How do I define a project which depends on another project in the same Buildfile?

StackOverflow https://stackoverflow.com/questions/12539122

  •  03-07-2021
  •  | 
  •  

Question

This seems like a simple task in Buildr, so I must be missing something obvious because I can't make it work. Suppose I have a directory with two files, like so:

test/lib/src/main/scala/MyLib.scala
test/app/src/main/scala/MyApp.scala

MyLib.scala is:

class MyLib {
  def hello() { println("Hello!") }
}

And MyApp.scala is:

object MyApp extends App {
  val ml = new MyLib
  ml.hello()
}

Building these with scalac is straightforward:

$ cd test
$ scalac lib/src/main/scala/MyLib.scala -d target/main/classes
$ scalac app/src/main/scala/MyApp.scala -cp target/main/classes -d target/main/classes
$ cd target/main/classes/
$ scala MyApp
Hello!

However, my naïve attempt to turn this into a Buildfile (in the test folder):

require 'buildr/scala'

lib_layout = Layout.new
lib_layout[:source, :main, :scala] = 'lib/src/main/scala'
app_layout = Layout.new
app_layout[:source, :main, :scala] = 'app/src/main/scala'

define 'mylib', :layout => lib_layout do
end

define 'myapp', :layout => app_layout do
  compile.with project('mylib')
end

fails with:

(in /test, development)
Building mylib
Compiling myapp into /test/target/main/classes
/test/app/src/main/scala/MyApp.scala:2: error: not found: type MyLib
  val ml = new MyLib
               ^
one error found
Buildr aborted!
RuntimeError : Failed to compile, see errors above

and if I run buildr --trace it's pretty clear that the reason scalac is failing is because the classpath does not include target/main/classes.

How do I make this happen? I know that separating the two projects may seem contrived, but I have something much more sophisticated in mind, and this example boiled the problem down to its essential components.

Was it helpful?

Solution

The idiomatic way to describe your project with Buildr would be to use sub-projects,

Note: buildfile below goes into the test/ directory.

require 'buildr/scala'

define "my-project" do
  define "lib" do
  end

  define "app" do
    compile.with project("lib").compile.target
  end
end

The two sub-projects lib and app are automatically mapped to the lib/ and app/ sub-directories and Buildr will automatically look for sources under src/main/scala for each.

OTHER TIPS

Buildr common convention for project layout looks for compiled classes in target/classes and target/test/classes. I see your build is placing classes into target/main/classes:

So you'll want to change your scala params to the expected location, or change the layout to include:

lib_layout[:target, :main, :scala] = 'target/main/classes'

If you also need to change the layout for test classes (I'm guessing you don't), use:

lib_layout[:target, :test, :scala] = ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top