Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my sourceDirectories setting have no effect in sbt?

Tags:

sbt

I'm reading the SBT Getting Started guide. That page shows the sourceDirectories setting as an example. To try it myself, I put the following in my build.sbt file, for a basic "hello world" project.

sourceDirectories in Compile := Seq(file("other"))

(Appending with += or ++= doesn't work either.)

I have source files in <base-dir>/other and in <base-dir>/src/main/scala. I ran sbt and typed compile. It ignored the setting:

> compile
[info] Compiling 1 Scala source to /Learning/Scala/proj1/target/scala-2.9.2/classes...
[error] /Learning/Scala/proj1/src/main/scala/hello.scala:7: not found: value Foo
[error]     println(Foo.foo)

The Foo object is defined in foo.scala in the other source directory.

What am I missing?

like image 297
Rob N Avatar asked Nov 27 '12 13:11

Rob N


2 Answers

tl;dr The answer by @schleichardt is a valid one - you need to add the following to the build.sbt file:

unmanagedSourceDirectories in Compile += file("other")

The explanation boils down to inspecting the dependencies of the compile task. Use inspect tree compile to find them out.

[proj1]> inspect tree compile
[info] compile:compile = Task[sbt.inc.Analysis]
[info]   +-compile:compile::compileInputs = Task[sbt.Compiler$Inputs]
[info]   | +-compile:scalacOptions = Task[scala.collection.Seq[java.lang.String]]
[info]   | +-compile:sources = Task[scala.collection.Seq[java.io.File]]
[info]   | +-*/*:sourcePositionMappers = Task[scala.collection.Seq[scala.Function1[xsbti.Position, scala.Option[xsbti.Position]]]]
[info]   | +-*/*:maxErrors = 100
[info]   | +-*:compilers = Task[sbt.Compiler$Compilers]
[info]   | +-compile:compile::streams = Task[sbt.std.TaskStreams[sbt.Init$ScopedKey[_ <: Any]]]
[info]   | | +-*/*:streamsManager = Task[sbt.std.Streams[sbt.Init$ScopedKey[_ <: Any]]]
[info]   | |
[info]   | +-compile:incCompileSetup = Task[sbt.Compiler$IncSetup]
[info]   | +-*/*:compileOrder = Mixed
[info]   | +-compile:dependencyClasspath = Task[scala.collection.Seq[sbt.Attributed[java.io.File]]]
[info]   | +-compile:classDirectory = target/scala-2.10/classes
[info]   | +-*/*:javacOptions = Task[scala.collection.Seq[java.lang.String]]
[info]   |
[info]   +-compile:compile::streams = Task[sbt.std.TaskStreams[sbt.Init$ScopedKey[_ <: Any]]]
[info]     +-*/*:streamsManager = Task[sbt.std.Streams[sbt.Init$ScopedKey[_ <: Any]]]
[info]

As you can see, the task depends on the compile:sources task. The task in turn depends on the compile:unmanagedSources task that uses the compile:unmanagedSourceDirectories setting.

[proj1]> inspect tree compile:sources
[info] compile:sources = Task[scala.collection.Seq[java.io.File]]
[info]   +-compile:unmanagedSources = Task[scala.collection.Seq[java.io.File]]
[info]   | +-compile:unmanagedSourceDirectories = List(/Users/jacek/sandbox/stackoverflow/proj1/src/main/scala, /Users/jacek/sandbox/stackoverflow/proj1/src/main/java, /Users/..
[info]   | | +-compile:javaSource = src/main/java
[info]   | | | +-compile:sourceDirectory = src/main
[info]   | | |   +-*:sourceDirectory = src
[info]   | | |   | +-*:baseDirectory = /Users/jacek/sandbox/stackoverflow/proj1
[info]   | | |   |   +-*:thisProject = Project(id: proj1, base: /Users/jacek/sandbox/stackoverflow/proj1, aggregate: List(), dependencies: List(), configurations: List(compile..
[info]   | | |   |
[info]   | | |   +-compile:configuration = compile
[info]   | | |
[info]   | | +-compile:scalaSource = src/main/scala
[info]   | | | +-compile:sourceDirectory = src/main
[info]   | | |   +-*:sourceDirectory = src
[info]   | | |   | +-*:baseDirectory = /Users/jacek/sandbox/stackoverflow/proj1
[info]   | | |   |   +-*:thisProject = Project(id: proj1, base: /Users/jacek/sandbox/stackoverflow/proj1, aggregate: List(), dependencies: List(), configurations: List(compile..
[info]   | | |   |
[info]   | | |   +-compile:configuration = compile
[info]   | | |
[info]   | | +-*:baseDirectory = /Users/jacek/sandbox/stackoverflow/proj1
[info]   | |   +-*:thisProject = Project(id: proj1, base: /Users/jacek/sandbox/stackoverflow/proj1, aggregate: List(), dependencies: List(), configurations: List(compile, runt..
[info]   | |
[info]   | +-*/*:excludeFilter = sbt.SimpleFileFilter@7ced8ea7
[info]   | +-*:baseDirectory = /Users/jacek/sandbox/stackoverflow/proj1
[info]   | +-*/*:unmanagedSources::includeFilter = sbt.SimpleFilter@1beb6bba
[info]   | +-*/*:sourcesInBase = true
[info]   |
[info]   +-compile:managedSources = Task[scala.collection.Seq[java.io.File]]
[info]     +-compile:sourceGenerators = List()
[info]

The compile:unmanagedSourceDirectories setting references "Unmanaged source directories, which contain manually created sources."

[proj1]> inspect compile:unmanagedSourceDirectories
[info] Setting: scala.collection.Seq[java.io.File] = List(/Users/jacek/sandbox/stackoverflow/proj1/src/main/scala, /Users/jacek/sandbox/stackoverflow/proj1/src/main/java, /Users/jacek/sandbox/stackoverflow/proj1/other)
[info] Description:
[info]  Unmanaged source directories, which contain manually created sources.
[info] Provided by:
[info]  {file:/Users/jacek/sandbox/stackoverflow/proj1/}proj1/compile:unmanagedSourceDirectories
[info] Defined at:
[info]  (sbt.Defaults) Defaults.scala:161
[info]  /Users/jacek/sandbox/stackoverflow/proj1/build.sbt:1
[info] Dependencies:
[info]  compile:javaSource
[info]  compile:scalaSource
[info]  *:baseDirectory
[info] Reverse dependencies:
[info]  compile:unmanagedSources
[info]  compile:sourceDirectories
[info] Delegates:
[info]  compile:unmanagedSourceDirectories
[info]  *:unmanagedSourceDirectories
[info]  {.}/compile:unmanagedSourceDirectories
[info]  {.}/*:unmanagedSourceDirectories
[info]  */compile:unmanagedSourceDirectories
[info]  */*:unmanagedSourceDirectories
[info] Related:
[info]  test:unmanagedSourceDirectories

The setting is of the scala.collection.Seq[java.io.File] type and to append an element to the seq, you can use += method.

Having said that, the build.sbt file should be as follows:

unmanagedSourceDirectories in Compile += (baseDirectory / "other").value

You don't have to use the baseDirectory setting, but it makes the base directory explicit.

like image 128
Jacek Laskowski Avatar answered Jan 24 '23 03:01

Jacek Laskowski


You can try this:

unmanagedSourceDirectories in Compile += file("other")
like image 36
Schleichardt Avatar answered Jan 24 '23 03:01

Schleichardt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!