Andy MacKinlay
Andy MacKinlay

Reputation: 1374

With SBT, how do I a specify an alternate project root other than the current directory for running a main class?

Normally SBT looks for the build files at ./build.sbt and ./project/Build.scala. Is it possible to specify an alternate project root, so I can build a project not in the current working directory? I'm looking essentially for an equivalent to mvn -f /path/to/pom.xml but the docs have not provided me with any obvious answers.

(I should note that I want to do this at runtime rather than compile time. Essentially, I want to use sbt run-main to run arbitrary classes from my project, since I hate manual classpath wrangling. For various boring reasons I may need to do this from arbitrary location since the code may need the working directory to be something other than the project directory, so using cd might not do what I want. It's so trivial in Maven - I just assumed, perhaps unfairly, that there would be a simple equivalent in SBT)

Upvotes: 3

Views: 3333

Answers (2)

Andy MacKinlay
Andy MacKinlay

Reputation: 1374

As I discovered from this other answer, the sbt-start-script plugin is a better tool for this than sbt run-main. You can simply run sbt stage and you get an invocation script, with classpaths resolved, at target/start. According to the documentation, it needs to be run from the build root directory for inter-project dependencies to work, but for my simple use cases, this doesn't seem to be a problem.

Upvotes: 0

Ezhik
Ezhik

Reputation: 874

I have something like this. I have project definition at X/build.sbt, X/MyOtherDefinitionWithSpecialThing/build.sbt, X/MySuperPublishConfig/build.sbt.

But my point of view to the problem is opposite. Instead of specify location of ./build.sbt and ./project/Build.scala I specify location of path to resources. The result is the same. It looks like:

sourceDirectory <<= (baseDirectory) (_ / ".." / "src")

target <<= (baseDirectory) (_ / ".." / "target")

This is allow to create single project with multiple definitions. This is worked with nested/hierarchical projects. But I use symbolic links (Linux OS) for hierarchical projects.

There is a file tree of one of my SBT plugins. Multiple build definitions and only one src/...

.
|-build.sbt
|-project
|---project
|-----target
|-------...
|---target
|-----...
|-project-0.11
|---build.sbt
|---project
|-----project
|-------target
|---------...
|-----target
|-------...
|-project-0.12
|---build.sbt
|---project
|-----project
|-------target
|---------...
|-----target
|-------...
|-...
|-src
|---main
|-----scala
|-------org
|---------...
|---sbt-test
|-----...
|-target
|---...

If this not solution of your problem please elaborate why you don't want use 'cd' command ;-)

-- For the updated use case:

I use shell wrapper and I have symlink to this one in every SBT project:

#!/bin/sh
#
here=$(cd $(dirname "$0"); pwd)
if [ ! -e "${here}/build.sbt" ]
then
  echo build.sbt lost
  exit
fi
cd ${here} 

LOCAL_BUILD=true sbt-0.12 "$@"

I simply write /path/to/my/project/sbt 'show name' for example or /path/to/my/project/sbt run-main in your case.

Upvotes: 0

Related Questions