I have a root project that depends on a subproject1. And subproject1 depends on subproject2.
Does that imply that I Can use subproject2's source code directly in root?
lazy val root =
Project(id = "root", base = file(".")).dependsOn(sub1)
lazy val sub1 =
Project(id = "sub1").dependsOn(sub2)
lazy val sub2 =
Project(id = "sub2")
Yes.
This can easily be checked.
build.sbt
name := "sbtdemo"
version := "0.1"
ThisBuild / scalaVersion := "2.13.4"
lazy val root =
Project(id = "root", base = file(".")).dependsOn(sub1)
lazy val sub1 =
Project(id = "sub1", base = file("sub1")).dependsOn(sub2)
lazy val sub2 =
Project(id = "sub2", base = file("sub2"))
sub2/src/main/scala/App.scala
object App {
def foo() = println("foo")
}
src/main/scala/Main.scala
object Main {
def main(args: Array[String]): Unit = {
App.foo() // foo
}
}
Yes. From Classpath dependencies by sbt:
lazy val core = project.dependsOn(util)
Now code in core can use classes from util. This also creates an ordering between the projects when compiling them; util must be updated and compiled before core can be compiled.
Related
I have a multi module sbt project. When I change some source code in a module, other modules don't see the changes in IntelliJ .
When I try to navigate, it goes to declaration, instead of navigating to the source it navigates to compiled jar file.
It works fine when I remove the jar from library dependencies in project settings. I think because it recompiles so works fine till next change. And sbt compiles works fine but I guess problem because of Build.scala settings, project dependencies can have order issues. Here is the dependencies;
lazy val root = Project(id = "xx-main", base = file("."), settings = commonSettings)
.aggregate(utils, models, commons, dao, te)
.dependsOn(utils, models, commons, dao)
lazy val utils = Project(id = "xx-utils", base = file("xx-utils"))
.settings(commonSettings: _*)
lazy val commons = Project(id = "xx-commons", base = file("xx-commons"))
.settings(commonSettings: _*)
.dependsOn(utils, models)
lazy val models =
Project(id = "xx-models", base = file("xx-models"), settings = commonSettings)
.dependsOn(utils)
lazy val dao = Project(id = "xx-dao", base = file("xx-dao"))
.settings(commonSettings: _*)
.dependsOn(utils, models)
lazy val te = Project(id = "xx-te", base = file("xx-te"))
.settings(commonSettings: _*)
.dependsOn(utils, models, dao, commons)
I am defining multiple JVM/JS cross projects. Each one contains some common JVM/JS scala code that I want to extract into a general common project that each project can depend on. Could someone recommend me the best way to define my build.scala files for the general and dependent projects?
CrossProject supports the normal dependsOn operation you are used to. So you can:
// call to settings needed so for an implicit conversion to kick in
lazy val common = crossProject.settings()
lazy val p1 = crossProject.dependsOn(common)
lazy val p2 = crossProject.dependsOn(common)
lazy val commonJVM = common.jvm
lazy val commonJS = common.js
lazy val p1JVM = p1.jvm
lazy val p1JS = p1.js
lazy val p2JVM = p2.jvm
lazy val p2JS = p2.js
There is a full example on GitHub.
You can create Multi-project builds
Let's say you have project structure like this;
root
project/Build.scala
project1
src/
project1.sbt
project2
src/
project2.sbt
projectN
src/
projectN.sbt
You can easily define dependencies in Build.scala
lazy val root = Project(id = "Main-Project",
base = file(".")) aggregate(project1, project2,..)
lazy val project2 = Project(id = "project2",
base = file("project1")).dependsOn(project1)
...
I ended up arriving at the solution below.
lazy val common = crossProject.in(file(".")).
settings(
).
jvmSettings(
).
jsSettings(
)
lazy val commonJVM = common.jvm
lazy val commonJS = common.js
...
lazy val p1 = crossProject.in(file(".")).
settings(
).
jvmSettings(
).
jsSettings(
).
jvmConfigure(_.dependsOn(ProjectRef(uri("../common"), "commonJVM"))).
jsConfigure(_.dependsOn(ProjectRef(uri("../common"), "commonJS")))
lazy val p1JVM = p1.jvm.
settings(...
lazy val p1JS = p1.js.
settings(...
I have an SBT project that aggregates over multiple projects like this:
object ClientCore extends Build {
/**
* This is the root project
*/
lazy val rootProj = Project(id = "clientcore", base = file(".")) aggregate(
utilsProj,
commonUiProj,
spatialMathProj,
sessionManagerProj,
lobbyProj,
)
/**
* This is a utils library
*/
lazy val utilsProj = Project(id = "utils", base = file("Utils"))
/**
* A shared library for UI elements
*/
lazy val commonUiProj = Project(id = "commonui", base = file("CommonUI"))
/**
* This is a spatial math library
*/
lazy val spatialMathProj = Project(id = "spatialmath", base = file("SpatialMath"))
lazy val sessionManagerProj = Project(id = "sessionmanager", base = file("sessionManager"),
settings = buildSettings ++ assemblySettings) settings(
outputPath in assembly := new File(s"$outDir\\SessionManagerClient.jar"),
jarName in assembly := "SessionManagerClient.jar",
test in assembly := {}
) dependsOn(utilsProj)
lazy val lobbyProj = Project(id = "lobby", base = file("Lobby"),
settings = buildSettings ++ assemblySettings) settings(
outputPath in assembly := new File(s"$outDir\\Lobby.jar"),
jarName in assembly := "Lobby.jar",
test in assembly := {}
) dependsOn(utilsProj)
}
For some reason some of the projects end up with a deep nesting of 'project' folders. For example Utils might look like: 'Util/project/project/project/project/...
I'm using Intellij's SBT plugin to sync the presentation but managing the project with SBT. I'm not certain whether this is an SBT issue or an Intellij one.
Thanks for any help you can provide.
Kurt
This is an IntelliJ issue (among many others related to the SBT plugin...)
I think you may have refreshed your config somewhere before defining a module and adding that module to the root project aggregates, which has a tendency to make a mess in IntelliJ.
This can be fixed in IntelliJ:
detach your project from IntelliJ
restart IntelliJ
reimport your project
I have an sbt build with 2 duplicated projects configuration. See example:
lazy val MyProjectOne = Project(id = "OneId", base = file("path/OneId"))
.dependsOn(moduleOne)
.settings(plugin.settings: _*)
.settings(defaultSettings: _*)
.settings(webSettings: _*)
.settings(libraryDependencies ++= commonTests)
lazy val MyProjectTwo = Project(id = "TwoId", base = file("path/TwoId"))
.dependsOn(moduleOne)
.settings(plugin.settings: _*)
.settings(defaultSettings: _*)
.settings(webSettings: _*)
.settings(libraryDependencies ++= commonTests)
It is obvious that MyProjectOne and MyProjectTwo differs only in id and base properties.
Is there a way to refactor sbt build like this:
lazy val template = Project()
.dependsOn(moduleOne)
.settings(plugin.settings: _*)
.settings(defaultSettings: _*)
.settings(webSettings: _*)
.settings(libraryDependencies ++= commonTests)
//Just as example:
lazy val MyProjectOne = Project(id = "OneId", base = file("path/OneId")).extends(template)
lazy val MyProjectTwo = Project(id = "TwoId", base = file("path/TwoId")).extends(template)
How can I do that with sbt?
Also
With maven I can define a parent project pom for that case. Is there analog in sbt?
I have a multiproject sbt build file like this
import sbt._
import Keys._
object TestBuild extends Build {
lazy val root = Project(id = "test",
base = file(".")) aggregate(core, handlers)
lazy val core = Project(id = "test-core",
base = file("core"))
lazy val handlers = Project(id = "test-handlers",
base = file("handlers")) dependsOn (core)
}
How can I build an assembly-jar that includes all the dependencies + core + handlers
Ok I solved this problem using
import sbt._
import Keys._
object TestBuild extends Build {
lazy val root = Project(id = "test",
base = file(".")) aggregate(core, handlers) dependsOn(core,handlers)
lazy val core = Project(id = "test-core",
base = file("core"))
lazy val handlers = Project(id = "test-handlers",
base = file("handlers")) dependsOn (core)
}
I put the assembly settings in the build.sbt file
You can use sbt-assembly plugin.
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.7.3")