I am building a Scala library using
ThisBuild / crossScalaVersions := List("2.13.8", "3.2.0")
This works as long as I use Scala 2 syntax for the entire project for compatibility. When I run command +publish from sbt, it publishes two modules, one prefixed with 2.13 and another one prefixed with _3.
I now want to build some exclusive functionality for Scala 3 users in the Scala 3 generated artefact. More specifically, I want to provide a macro derivation for scala 3 users.
How do I do that?
Related
I would like to cross-build some of my Bazel targets to Scala 2.12 and 2.13. As a further point of complexity, I need to be able to express cross-target dependencies (eg. some 2.13 target may have a Bazel dependency on a 2.12 target).
Note: this isn't a regular library dependency (eg. with the dependency 2.12-built JAR showing up on the class path when compiling the 2.13 JAR), as that would almost surely result in issues due to having two incompatible versions of the Scala standard library on the class path. Rather, this is just a case where I need the dependency JAR built so I can use it in some integration tests in the 2.13 target.
What I've found online so far...
This issue from rules_scala seems it doesn't support baking the Scala version into the target and instead you have to pick the Scala version globally.
This Databricks post has a cross-building section that is exactly what I think I would like (eg. one target generated per library per supported Scala version), but the snippets in that post don't seem to be backed by any runnable Bazel code.
This later post by Databricks also hints at a cross_scala_lib rule, but also doesn't have any accompanying code.
The sbt documentation tells me I can suffix the scala version in order to get sbt to pick up the sources when building with that version.
https://www.scala-sbt.org/1.x/docs/Cross-Build.html#Scala-version+specific+source+directory
It doesn't say how I can specify the suffix so that I can match multiple scala versions in one directory. I need one to match both 2.12 and 2.13, and one to match 2.11.
I found a few example of that in a few libraries like zio or cats. The suffixes looked like -2.12+ or -2.12-2.13. When applied to my build though, sbt doesn't seem to find these paths, and compilation fails because some classes are not found. If I separate them with -2.12 and -2.13 it works, but I'd have to duplicate code.
You can try sbt new scala/scala-seed.g8 and rename src/main/scala to src/main/scala-2.12+ and see that it doesn't work, while it works when renamed to src/main/scala-2.13.
Can someone point me to what I'm missing?
I've tried sbt versions 1.3.10 and 1.2.8.
I modified the source code of scala compiler and built it. Now I want to test this compiler. However, many existing scala projects use sbt as build tool. So I wonder if it is possible to replace the official scala compiler used by sbt with the scala compiler built by myself.
See http://www.scala-sbt.org/1.0/docs/Configuring-Scala.html#Using+Scala+from+a+local+directory:
The result of building Scala from source is a Scala home directory <base>/build/pack/ that contains a subdirectory lib/ containing the Scala library, compiler, and other jars. The same directory layout is obtained by downloading and extracting a Scala distribution. Such a Scala home directory may be used as the source for jars by setting scalaHome. For example,
scalaHome := Some(file("/home/user/scala-2.10/"))
If you want to publish the compiler, use #ipoteka's answer.
According to docs it's straightforward:
managedScalaInstance := false
libraryDependencies += "yourPackage" % "yourScalaCompiler" % version
Don't forget to publish-local you compiler first.
Im working on several Scala projects and liberties
Some of them work on scala 2.10.x version and some of them work on the 2.11.X version .
My default $scala_home version is 2.11 so if a build something by default it will be built in the 2.11 version? (thats true??)
My main issue is with Apache Spark and Kafka that are working fine with the 2.10.x version .
How are handling multi version dependency on one machine.
thanks,
miki
I would not install a global Scala on the system, neither do I have a $SCALA_HOME. I think most people would recommend against it.
If you use a build tool like sbt, that will take care of applying the correct Scala version as required by your build definition. In sbt, you have a file build.sbt that contains an assignment scalaVersion := "2.10.4" or scalaVersion := "2.11.5" depending on which version you want to use. It keeps all the different Scala versions neatly separated in a cache directory and won't confuse them.
If I understood scalajs docs correctly it allows only one javascript generation per project.
Is there a way to avoid this limitation?
Currently I created scalajs sub project for Play framework. In this sub project I planned to create all scalajs apps for the service I am working on. Now I found this limitation and it's really confusing and annoying, because the only two solutions I can think of are:
create one "mega-script" which isn't acceptable for me
for every scalajs app create separate sub projects
They both are really not acceptable for a big project.
Every scalajs in it's own subproject and manage everything via SBT MutliProject
Here is somewhat complex example of play project, that has 6+ subprojects that compiles to one single file. scala-js-binding
Check the Build.scala
lazy val preview = (project in file(".")).enablePlugins(PlayScala) settings(previewSettings: _*) dependsOn shared dependsOn bindingPlay aggregate frontend
//aggregate scalaJs
lazy val frontend = Project(
id = "frontend",
base = file("frontend") ) dependsOn shared dependsOn binding
...
scalajsOutputDir := baseDirectory.value / "public" / "javascripts" / "scalajs",
//fastOptJs - not optimized (3Mb)
compile in Compile <<= (compile in Compile) dependsOn (fastOptJS in (frontend, Compile)),
//fullOptJS - fully optimized (330k)
dist <<= dist dependsOn (fullOptJS in (frontend, Compile)),
Scala.js is indeed designed to generate one JavaScript output per project. There is virtually no way to change this.
However, this is not a restriction of Scala.js. Scala/Java themselves behave the same way: you cannot generate two .jars from a single sbt project for a Scala/Java application. So I do not see why Scala.js should behave any differently.
Use multiple projects in your sbt build for this, as suggested by #user3430609.