Setting up Cross Compilation for my SBT Auto plugin project - scala

I am writing a SBT Auto Plugin. This is my build.sbt file
lazy val foo = (project in file(".")).settings(
name := "foo",
sbtPlugin := true,
organization := "com.foo",
crossScalaVersions = Seq("2.11.8", "2.12.4")
)
but I get the error
overloaded method value settings with alternatives:
(ss: sbt.Def.SettingsDefinition*)sbt.Project <and>
=> Seq[sbt.Def.Setting[_]]
cannot be applied to (sbt.Def.Setting[String], sbt.Def.Setting[Boolean], sbt.Def.Setting[String], crossScalaVersions: Seq[String])
lazy val foo = (project in file(".")).settings(
^
[error] sbt.compiler.EvalException: Type error in expression
[error] sbt.compiler.EvalException: Type error in expression
[error] Use 'last' for the full log.
Project loading failed: (r)etry, (q)uit, (l)ast, or (i
My objective is that when I do sbt publish I publish two jar files. one for scala 2.11 and other for scala 2.12

you have to give it like crossScalaVersions := Seq("2.11.8", "2.12.4") instead of crossScalaVersions = Seq("2.11.8", "2.12.4").
You can see more here Cross-Building a Project.

Related

SBT error: "Runtime reference to undefined setting"

I am trying to reference another Github project as a build dependency in sbt using the following code that sits in build.sbt:
lazy val dependency = RootProject(uri("..."))
// The Play project itself
lazy val root = (project in file("."))
.enablePlugins(Common, PlayScala, GatlingPlugin)
.configs(GatlingTest)
.settings(inConfig(GatlingTest)(Defaults.testSettings): _*)
.dependsOn(dependency)
.settings(
name := """play-scala-rest-api-example""",
scalaSource in GatlingTest := baseDirectory.value / "/gatling/simulation"
)
And I get the error:
Runtime reference to undefined setting:
[error]
[error] ProjectRef(uri("..."), "dependency")

Adding SBT as a dependency in SBT file

I am writing few sbt tasks in a scala file. These SBT tasks will be imported into many other projects.
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "com.example",
scalaVersion := "2.11.8",
version := "1.0.0"
)),
name := "sbttasks",
libraryDependencies ++= Seq(
"org.scala-sbt" % "sbt" % "1.0.0" % "provided"
)
)
I get a compilation error
error] java.lang.RuntimeException: Conflicting cross-version suffixes in: org.scala-lang.modules:scala-xml, org.scala-lang.modules:scala-parser-combinators
[error] at scala.sys.package$.error(package.scala:27)
[error] at sbt.librarymanagement.ConflictWarning$.processCrossVersioned(ConflictWarning.scala:39)
[error] at sbt.librarymanagement.ConflictWarning$.apply(ConflictWarning.scala:19)
[error] at sbt.Classpaths$.$anonfun$ivyBaseSettings$64(Defaults.scala:1995)
[error] at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error] at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:39)
[error] at sbt.std.Transform$$anon$4.work(System.scala:66)
[error] at sbt.Execute.$anonfun$submit$2(Execute.scala:262)
[error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error] at sbt.Execute.work(Execute.scala:271)
[error] at sbt.Execute.$anonfun$submit$1(Execute.scala:262)
[error] at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:174)
[error] at sbt.Completion
I don't want to write the custom tasks in build.sbt itself (as the SBT documentation shows) because then I won't be able to import my custom tasks into other projects.
To write reusable tasks that you can "import" in different projects, you need to make an sbt plugin.
If you have a multi-project build and want to reuse your tasks in the subprojects, you can create a file project/MyPlugin.scala with
import sbt._
import sbt.Keys._
object MyPlugin extends AutoPlugin {
override def trigger = noTrigger
object autoImport {
val fooTask = taskKey[Foo]("Foo description")
val barTask = taskKey[Bar]("Bar description")
}
import autoImport._
override lazy val projectSettings = Seq(
fooTask := { ??? },
barTask := { ??? }
)
}
Then to enable this plugin (i.e. make those tasks available) in a subproject, you can write this in your build.sbt:
lazy val subproject = (project in file("subproject"))
.enablePlugins(MyPlugin)
On the contrast, if you want to reuse these tasks in other unrelated projects, you need to make this plugin a separate project and publish it. It's a normal sbt project, but instead of an explicit sbt dependency, you write in its build.sbt:
sbtPlugin := true
And the code defining tasks goes to src/main/scala/ (like in a normal project).
You can read in detail about writing plugins in the sbt documentation.
Change version of "org.scala-sbt" to "1.0.0-M4"
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "com.example",
scalaVersion := "2.11.8",
version := "1.0.0",
name := "sbttasks"
)),
libraryDependencies ++= Seq(
"org.scala-sbt" % "sbt" % "1.0.0-M4" % "provided"
)
)
For entire compatibility matrix check
https://mvnrepository.com/artifact/org.scala-sbt/main

SBT Run Main Method from a Sub Project

I am writing a project which contains scala macros. This is why I have organized my project into two sub projects called "macroProj" and "coreProj". The "coreProj" depends on "macroProj" and also contains the main method to run my code.
My requirement is that when I do a sbt run from the root project, the main method is taken from the coreProj sub project. I search and found a thread which has a solution for this
sbt: run task on subproject
Based on this my build.sbt looks like
lazy val root = project.aggregate(coreProj,macroProj).dependsOn(coreProj,macroProj)
lazy val commonSettings = Seq(
scalaVersion := "2.11.7",
organization := "com.abhi"
)
lazy val coreProj = (project in file("core"))
.dependsOn(macroProj)
.settings(commonSettings : _*)
.settings(
mainClass in Compile := Some("demo.Usage")
)
lazy val macroProj = (project in file("macro"))
.settings(commonSettings : _*)
.settings(libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value)
mainClass in Compile <<= (run in Compile in coreProj)
But when I do sbt run from the root directory. I get an error
/Users/abhishek.srivastava/MyProjects/sbt-macro/built.sbt:19: error: type mismatch;
found : sbt.InputKey[Unit]
required: sbt.Def.Initialize[sbt.Task[Option[String]]]
mainClass in Compile <<= (run in Compile in coreProj)
^
[error] Type error in expression
In sbt, mainClass is a task that will return an entry point to your program, if any.
What you want to do is to have mainClass be the value of mainClass in coreProj.
You can achieve that this way:
mainClass in Compile := (mainClass in Compile in coreProj).value
This could also be achieved with
mainClass in Compile <<= mainClass in Compile in coreProj
However, the preferred syntax is (...).value since sbt 0.13.0.

Error while using aspectj with Scala

I am having an application in scala. I need to use AOP for one of the functionality. I used the plugin sbt-aspectj . Everything is working fine when I run using the sbt console. However, I am not able to make it work when using the executable jar. I tried the the sample code provided in the sbt-aspect git page. But, I am getting the errors as
[warn] warning incorrect classpath: D:\source\jvm\modules\scala\frameworks\aspectjTracer\target\scala-2.11\classes
[warn] Missing message: configure.invalidClasspathSection in: org.aspectj.ajdt.ajc.messages
[error] error no sources specified
.
[trace] Stack trace suppressed: run 'last aspectjTracer/aspectj:ajc' for the full output.
[error] (aspectjTracer/aspectj:ajc) org.aspectj.bridge.AbortException: ABORT
[error] Expected project ID
[error] Expected configuration
[error] Expected ':' (if selecting a configuration)
[error] Expected key
[error] Not a valid key: aspectjTracker (similar: aspectjSource, aspectj-source, aspectjDirectory)
[error] last aspectjTracker/aspectj:ajc
[error]
My Build.scala is given below :
object frameworkBuild extends Build {
import Dependencies._
val akkaV = "2.3.6"
val sprayV = "1.3.1"
val musterV = "0.3.0"
val common_settings = Defaults.defaultSettings ++
Seq(version := "1.3-SNAPSHOT",
organization := "com.reactore",
scalaVersion in ThisBuild := "2.11.2",
scalacOptions ++= Seq("-unchecked", "-feature", "-deprecation"),
libraryDependencies := frameworkDependencies ++ testLibraryDependencies,
publishMavenStyle := true,
)
connectInput in run := true
lazy val aspectJTracer = Project(
"aspectjTracer",
file("aspectjTracer"),
settings = common_settings ++ aspectjSettings ++ Seq(
// input compiled scala classes
inputs in Aspectj <+= compiledClasses,
// ignore warnings
lintProperties in Aspectj += "invalidAbsoluteTypeName = ignore",
lintProperties in Aspectj += "adviceDidNotMatch = ignore",
// replace regular products with compiled aspects
products in Compile <<= products in Aspectj
)
)
// test that the instrumentation works
lazy val instrumented = Project(
"instrumented",
file("instrumented"),
dependencies = Seq(aspectJTracer),
settings = common_settings ++ aspectjSettings ++ Seq(
// add the compiled aspects from tracer
binaries in Aspectj <++= products in Compile in aspectJTracer,
// weave this project's classes
inputs in Aspectj <+= compiledClasses,
products in Compile <<= products in Aspectj,
products in Runtime <<= products in Compile
)
)
lazy val frameworks = Project(id = "frameworks", base = file("."), settings = common_settings).aggregate( core, baseDomain,aspectJTracer,instrumented)
lazy val core = Project(id = "framework-core", base = file("framework-core"), settings = common_settings)
lazy val baseDomain = Project(id = "framework-base-domain", base = file("framework-base-domain"), settings = common_settings).dependsOn(core,aspectJTracer,instrumented)
}
Does anyone know how to fix this? I posted this in the sbt-aspectj github page and waiting for a response there as well. But I am in a little hurry to fix this. Your help will be really appreciated.
Finally the problem is resolved. I had added javaagent in the build.scala. But, while running with the sbt-one-jar, it was not taking that jar. So I have manually provided the javaagent as the aspectweaver jar file and it worked. However, it is almost taking 3-4 minutes to start the jar file with the aspect.
Sometime it is even taking 15 min to start the jar file due to the aspectjwaver. I am not sure if this is problem with aspectj or sbt-one-jar, I guess its with the one-jar.
has anyone else faced the same issue ? I don't see any activity in sbt-one-jar, so asking it here.

sbt error when forking is enabled

Sbt produce an error when there is this line:
fork in run := true
in this build.scala file
The surrounding build.scala content
lazy val scalafxDemos = Project(
id = "scalafx-demos",
base = file("scalafx-demos"),
settings = scalafxSettings ++ Seq(
libraryDependencies ++= Seq(
scalatest % "test",
junit % "test"),
unmanagedListing,
description := "The ScalaFX demonstrations",
fork in run := true,
fork in Test := true,
parallelExecution in Test := false,
// print junit-style XML for CI
testOptions in Test <+= (target in Test) map {
t => Tests.Argument(TestFrameworks.ScalaTest, "-u", "%s" format (t / "junitxmldir"))
},
The error produced:
[error] /Users/hanxue/Github/scalafx/project/build.scala:113: overloaded method value in with alternatives:
[error] (scope: sbt.Scope)sbt.SettingKey[Boolean] <and>
[error] (c: sbt.ConfigKey)sbt.SettingKey[Boolean] <and>
[error] (t: sbt.Scoped)sbt.SettingKey[Boolean] <and>
[error] (p: sbt.Reference)sbt.SettingKey[Boolean]
[error] cannot be applied to (run.type)
[error] fork in run := true,
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
I can avoid the error by changing the line to fork := true, though that does satisfy the intent of forking only in run and Test. How can I fix this without forcing everything else to be forked?
That probably means run is coming from somewhere else. You might try an explicit Keys.run to see if this is the case.