Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have SBT skip cross compile for a given sub-project?

Tags:

sbt

I've run into a couple related cases with SBT that have me stumped. Is there a way to tell SBT to skip a sub project entirely for certain scala versions when you're cross compiling?

Here are two examples where this would be useful.

1) A build with three projects A, B, and C. Both A and B are scala projects, and have 'scalaVersions ++= Seq("2.11.2", "2.10.4") in their settings. Project C is a pure-Java artifact, and thus I've excluded the Scala libraries from it's dependencies. I'd like A and B to depend on C, but ideally I'd only like to build C just once. If I use the default behavior and do "+publish" from the root aggregator project, I get two copies of C-1.0.0.jar produced, and SBT attempts to publish it twice, which is of course a no-no for a maven repository.

2) A build with multiple scala projects, but where one project should only build against a single Scala version. I've tried defining 'scalaVersions' in the settings for this project to hold only one version where the other projects have two, but again "+publish" from a root aggregator seems to ignore this and still compiles it twice, with the second time failing because it's dependencies aren't available for that Scala version. This project is a leaf node in the dependency graph, so it's a perfectly fine thing to want to do logically.

For case #2, I've thought of setting the source dirs for the 'bad' scala version to /dev/null or something similar, but that still actually runs the build and produces an empty artifact. I know I could probably go in and find all of the relevant keys and do something like

publishArtifact := if(scalaBinaryVersion.value == "2.10") false else publishArtifact.value

and then hunt down all of the other related settings/tasks (compile, compile in Test, test in Test, packageBin, etc) but that seems pretty hack-ish. Is there a 'skip' setting somewhere?

like image 835
dpratt Avatar asked Aug 31 '14 21:08

dpratt


People also ask

What is ThisBuild in sbt?

Typically, if a key has no associated value in a more-specific scope, sbt will try to get a value from a more general scope, such as the ThisBuild scope. This feature allows you to set a value once in a more general scope, allowing multiple more-specific scopes to inherit the value.

What is crossScalaVersions?

SBT's crossScalaVersions allows projects to compile with multiple versions of Scala. However, crossScalaVersions is a hack that reuses projects by mutates settings.

Does sbt run compile?

sbt is a popular tool for compiling, running, and testing Scala projects of any size. Using a build tool such as sbt (or Maven/Gradle) becomes essential once you create projects with dependencies or more than one code file.

Which is the correct way to add dependencies in sbt file?

If you have JAR files (unmanaged dependencies) that you want to use in your project, simply copy them to the lib folder in the root directory of your SBT project, and SBT will find them automatically.


2 Answers

I wrote sbt-doge to address task aggregation across subprojects respecting their crossScalaVersions. For Java projects you might need a dummy crossScalaVersion entry.

like image 120
Eugene Yokota Avatar answered Oct 04 '22 16:10

Eugene Yokota


The plugin sbt-doge can be used to specify a crossScalaVersion setting in each subproject.

First, add the line addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.5") to your projects/plugins.sbt.

To avoid the ridiculous doge syntax ("such compile", really?) you need to enablePlugins(CrossPerProjectPlugin) in your root project. With this, you can add a plus sign before your sbt commands, and they will honor the cross build settings. Just like this: + compile.

like image 26
willena Avatar answered Oct 04 '22 16:10

willena