Is there any way to set the Annotation processor output path in sbt?
Currently it generates the files into:
target/scala-2.11/classes
However I would prefer
target/scala-2.11/src_managed
Something like
// in build.sbt:
// create managed source directory before compile
compile in Compile <<= (compile in Compile) dependsOn Def.task { (managedSourceDirectories in Compile).value.head.mkdirs() },
// tell the java compiler to output generated source files to the managed source directory
javacOptions in Compile ++= Seq("-s", (managedSourceDirectories in Compile).value.head.getAbsolutePath),
It's slightly more ergonomic to configure sourceManaged instead of managedSourceDirectories.
Add to a sbt module's settings in build.sbt:
Compile / javacOptions ++= Seq("-s", (Compile / sourceManaged).value.getAbsolutePath)
You can also drop this plugin into the project folder
package custom.sbt
import sbt.{Def, _}
import sbt.Keys._
object Compiler extends AutoPlugin {
override def trigger = allRequirements
override def buildSettings: Seq[Def.Setting[_]] = Seq(
Compile / javacOptions ++= Seq("-source", "11", "-target", "11"),
scalacOptions ++= Seq(
"-target:11" // Target JRE 11
)
)
override def projectSettings: Seq[Def.Setting[_]] = Seq(
Compile / javacOptions ++= Seq("-s", (Compile / sourceManaged).value.getAbsolutePath)
)
}
in sbt 0.13.15
compile := ((compile in Compile) dependsOn Def.task {
(sourceManaged in Compile).value.mkdirs()
}).value,
javacOptions in Compile ++= Seq("-s", s"${sourceManaged.value}/main")
Related
I have a sbt project with multiple sub modules which look like this:
--\ root
-- module 1
-- module 2
Using packageBin, I can get two zip files: module1.zip and module2.zip.
This is my build.sbt:
import Dependencies._
import NativePackagerHelper._
lazy val commonSettings = Seq(
organization := "com.zhyea.sbt",
version := "0.1-SNAPSHOT",
scalaVersion := "2.11.12",
exportJars := true,
artifactName := {
(sv: ScalaVersion, module: ModuleID, artifact: Artifact) => artifact.name + "." + artifact.extension
}
)
lazy val module2 = project.settings(commonSettings).settings()
.enablePlugins(JavaAppPackaging, UniversalPlugin)
.settings(libraryDependencies ++= module2Dependencies)
lazy val module1 = project.settings(commonSettings)
.enablePlugins(JavaAppPackaging, UniversalPlugin)
.settings(libraryDependencies ++= module1Dependencies)
lazy val root = project.in(file("."))
.settings(commonSettings)
.aggregate(module2, module1)
.enablePlugins(JavaAppPackaging, UniversalPlugin)
.dependsOn(module2, module1).configs()
mappings in Universal ++= directory("module2/target/universal")
The mappings in Universal ++= directory("module1/target/universal")
Now I want to execute the packageBin task at root and add sub module zips into root.zip.
The problem is that when the root module executes packageBin task, the sub modules' packageBin tasks haven't finished, and the root cannot get module1.zip and mudule2.zip.
How can I tell sbt to execute the packageBin task in order?
i just pack all sub modules' files into one zip by adding a new module named pack.
I am writing a akka application. While creating far jar of application , I dont want scala libraries to be packaged with the jar. My build.sbt looks as follows:
lazy val root = (project in file(".")).
settings(
name :="akka-app",
version :="1.0",
scalaVersion :="2.10.4",
mainClass in Compile := Some("sample.hello.HelloWorld")
)
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3.4" % "provided",
"com.typesafe" % "config" % "1.2.1"
)
// META-INF discarding
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
{
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
}
But this sbt packages scala with jar. I want only com.typesafe.config library to be present in the jar. Any solution how to achieve this?
You can exclude Scala by modifying the option in the assemblyOption setting:
assemblyOption in assembly :=
(assemblyOption in assembly).value.copy(includeScala = false)
I have something like this in my build.sbt:
lazy val someDeps = Seq(
libraryDependencies += "com.example" %% "foo" % "1.3.37",
// more
)
lazy val some_library = project.in(file("libs/somelibrary")).
settings(commonSettings).
settings(
// project-specific settings
libraryDependencies ++= someDeps
)
lazy val something_with_deps_provided = project.in(file("swdp")).
settings(commonSettings).
settings(
// project-specific settings
libraryDependencies ++= someDeps.map(d => d % "provided")
).dependsOn(some_library)
When I now use the sbt-assembly-plugin to create the assembly of something_with_deps_provided, it still puts the dependencies into the resulting jar, ignoring the provided. Is it possible to set a transitive dependency to provided later and if yes, how is it done?
In cases like this, excludeDependencies can be used as described in
SBT manual here:
Exclude Transitive Dependencies.
With your example:
lazy val something_with_deps_provided = project.in(file("swdp"))
.settings(commonSettings)
.dependsOn(some_library)
.settings(
// project-specific settings
excludeDependencies ++= someDeps.map { d =>
ExclusionRule(
organization = d.organization,
name = d.name
)
}
)
The dependencies from someDeps will no longer be included in the
assembly JAR for something_with_deps_provided project.
These are my project's dependencies:
libraryDependencies ++= Seq(
javaJdbc,
javaEbean,
cache,
javaWs,
"com.company" % "common_2.11" % "2.3.3"
)
In com.company.common_2.11-2.3.3 there is a jar file common_2.11-2.3.3-adtnl.jar.
How can I during compilation process in build.sbt tell SBT to extract its contents to specific folder in my project?
Use the following in build.sbt:
def unpackjar(jar: File, to: File): File = {
println(s"Processing $jar and saving to $to")
IO.unzip(jar, to)
jar
}
resourceGenerators in Compile += Def.task {
val jar = (update in Compile).value
.select(configurationFilter("compile"))
.filter(_.name.contains("common"))
.head
val to = (target in Compile).value / "unjar"
unpackjar(jar, to)
Seq.empty[File]
}.taskValue
It assumes that "common" is a unique part amongst all of your dependencies. You'd need to fix filter otherwise.
It also assumes that you don't really want the files at compile, but a bit later when package is called. You'd need to move the code between Def.task{...} to compile in Compile block like:
compile in Compile <<= (compile in Compile).dependsOn(Def.task {
val jar = (update in Compile).value
.select(configurationFilter("compile"))
.filter(_.name.contains("common"))
.head
val to = (target in Compile).value / "unjar"
unpackjar(jar, to)
Seq.empty[File]
})
I'm using the sbt-xjc plugin to generate my xml classes.
The default value of sourceManaged is prepended with xjc. I want to remove xjc. How should I do that?
For me, adding the following to project/build.scala worked:
++ Seq(
sourceManaged in (Compile, SbtXjcPlugin.xjc) <<= sourceManaged
The whole file looks like this:
import com.github.retronym.sbtxjc.test.BaseScriptedTestBuild
import com.github.retronym.sbtxjc.SbtXjcPlugin
import sbt._
import Keys._
object build extends BaseScriptedTestBuild {
lazy val root = {
Project(
id = "main",
base = file("."),
settings = Defaults.defaultSettings ++ scriptedTestSettings ++ SbtXjcPlugin.xjcSettings ++ Seq(
resolvers += "Java Net" at "http://download.java.net/maven/2/"
)++ Seq(
sourceManaged in (Compile, SbtXjcPlugin.xjc) <<= sourceManaged
)
);
}
}
With this config in build.sbt, XJC generates the classes directly in src_managed/main.
SbtXjcPlugin.xjcSettings ++ Seq(
sources in (Compile, xjc) <<= baseDirectory map (_ / "xsd" ** "*.xsd" get),
sourceManaged in (Compile, xjc) <<= sourceManaged / "main"
)
XJC will look for xsd files in /xsd and output the generated classes in /target/scala-2.x/src_managed/main