Getting JavaCV 0.9 platform binaries to download automatically with SBT - sbt

I have an SBT application that is using JavaCV on Windows.
My build.sbt brings in JavaCV and its dependencies using:
classpathTypes += "maven-plugin"
libraryDependencies += "org.bytedeco" % "javacv" % "0.9"
This pulls JavaCV and its dependents (JavaCPP), but it isn't pulling the JAR with the platform specific libraries (opencv-windows-x86_64.jar). This allows me to build, but I get "UnsatisfiedLinkError: no jniopencv_core in java.library.path"
Based on http://www.warski.org/blog/2014/01/using-javacv-with-sbt I also tried
libraryDependencies += "org.bytedeco" % "javacv" % "0.9" classifier "windows-x86_64"
SBT fails trying to resolve that dependency because it is looking for http://repo1.maven.org/maven2/org/bytedeco/javacv/0.9/javacv-0.9-windows-x86_64.jar which doesn't exist.
If I copy opencv-windows-x86_64.jar to the lib directory then everything works, but that defeats the point of using a dependency manager.
Does anyone know how to make SBT properly resolve the platform specific jars for JavaCV 0.9?

Using the -Dplatform.dependencies=true option on the command line should do the trick!

I wrote an SBT plugin to make OpenCV dependency handling (yes, including platform dependencies) a one liner: https://github.com/lloydmeta/sbt-opencv
Simply add this to your project/plugins.sbt:
addSbtPlugin("com.beachape" % "sbt-opencv" % "1.4")

Related

how do I put sbt-assembly in artifactory and have sbt retrieve it

For some reason I am having trouble downloading the sbt-assembly plugin using
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.7")
from plugins.sbt. It says the pom is not found. I'm using scala 2.12.10 at the moment but this has been an irritation with 2.13.1, too. As an alternative, I tossed it in an artifactory repository. When sbt concocts the URL to retrieve the pom, it comes up with
http:/.../com/eed3si9n/sbt-assembly_2.12_1.0/0.14.7/sbt-assembly-0.14.7.pom
as opposed to
http:/.../com/eed3si9n/sbt-assembly/0.14.7/sbt-assembly-0.14.7.pom
which will actually retrieve it. Any insight would be appreciated.
Looking under custom resolvers in the sbt reference manual tells you to match relevant values from the build. Maybe something like:
resolvers += Resolver.url("red angus", new java.net.URL(
"http:/..."))(
Patterns("[organisation]/[module]/[revision]/[artifact]-[revision].[ext]") ).
withAllowInsecureProtocol(true)

Why two different versions of sbt in the project

In my Play project I notice that build.properties has sbt version addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.12")
and build.properties has sbt.version=0.13.15.
1) Why are there two enteries?
2) What is the difference between them
3) Should their versions be different?
There is a difference between SBT proper and SBT plugin. Play Framework is an SBT plugin. The version of SBT is specified in project/build.properties:
sbt.version=0.13.15
whilst the version of Play SBT plugin is specified in project/plugins.sbt:
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.12")
Scala Play SBT plugin (PlayScala) is enabled in build.sbt like so:
lazy val root = (project in file(".")).enablePlugins(PlayScala)
SBT plugins enrich build definitions with additional useful tasks, commands, settings, and dependencies. Here are some examples from Play SBT plugin:
object PlayKeys {
val playDefaultPort = SettingKey[Int]("playDefaultPort", "The default port that Play runs on")
val playDefaultAddress = SettingKey[String]("playDefaultAddress", "The default address that Play runs on")
val playRunHooks = TaskKey[Seq[PlayRunHook]]("playRunHooks", "Hooks to run additional behaviour before/after the run task")
...
So for example to change the default port that Play runs on we can define in build.sbt:
PlayKeys.playDefaultPort := 9009
Note when upgrading SBT version we need to make sure it is compatible with corresponding Play SBT plugin. For example, to use Play with SBT 1 we need to update Play sbt-plugin to 2.6.6.
SBT plugin best practice artifact naming convention encurages the following naming scheme:
sbt-$projectname
For example, sbt-scoverage, sbt-buildinfo, sbt-release, sbt-assembly, however Play named it sbt-plugin, which arguably can be confusing.

How can I specify a different library jar for a sbt plugin dependency?

I'm using the sbt-scalariform plugin with sbt, which is built with a dependency on the default version of scalariform (mdr/scalariform). I'd like it to use a different/forked version of scalariform (daniel-trinh/scalariform) for my project.
Is there a configuration I can use in sbt in my project to specify the version of scalariform I want or do I need to fork/build my own custom version of sbt-scalariform built against daniel-trinh/scalariform?
(I'm not worried about compatibility between the two versions of sbt-scalariform. sbt-scalariform is really just a wrapper.)
I can add dependencies to my project but that's for my compiled code, not the build process itself, right (Build.scala in my case)?
addSbtPlugin(org % name % version exclude (scalariformorg, scalariform))
libraryDependencies += scalariformorg % scalariformorg % version
Fill in the fields as appropriate for what you want to replace. This goes into project/plugins.sbt

Downloading source jars in sbt?

I pulled down the sources and build/published it locally. I want to debug into sources jars. When I publish it locally, I clearly see it also publishes source jars.
[info] published securesocial-testkit_2.10 to local\ws.securesocial\securesocial-testkit_2.10\master-SNAPSHOT\srcs\securesocial-testkit_2.10-sources.jar
I don't know how to reference this jar.
Changing "ws.securesocial" %% "securesocial" % "master-SNAPSHOT" to "ws.securesocial" %% "securesocial" % "master-SNAPSHOT-sources" doesn't work.
Add withSources() to the dependency definition.
From Download Sources in the official documentation of sbt:
Downloading source and API documentation jars is usually handled by an
IDE plugin. These plugins use the updateClassifiers and
updateSbtClassifiers tasks, which produce an Update Report referencing
these jars.
To have sbt download the dependency's sources without using an IDE
plugin, add withSources() to the dependency definition. For API jars,
add withJavadoc(). For example:
libraryDependencies += "org.apache.felix" % "org.apache.felix.framework" % "1.8.0" withSources() withJavadoc()
Note that this is not transitive. Use the update-*classifiers tasks
for that.
You can also run sbt update-classifiers to download sources and javadoc jars for all project dependencies at once
For sbt 1.0, command is sbt updateClassifiers
For me, it worked better with
sbt ';reload plugins; updateClassifiers'

Generating Java Sources with sbt JFlex plugin

I am pulling my hair using the sbt-jflex plugin to generate Java sources via JFlex, before the main javac phase of sbt (0.12).
The plugin is a clone of the ANTLR plugin, and I found this question which shows how to use the latter.
So I have the following in project/plugins.sbt:
addSbtPlugin("org.scalanlp" % "sbt-jflex" % "0.1-SNAPSHOT")
And this in ./build.sbt:
jflexSettings
sourceGenerators in Compile <+= generate in jflex
But I must be either doing something wrong, or the javac phase comes before the source generators, because when I run sbt compile, I never see the message "JFlex: Using JFlex version X to generate source files". Instead sbt goes straight to compile the Java sources
[info] Compiling 91 Java sources to ...
And then fails because the JFlex output is missing at that stage. Running source-directories shows that src/main/jflex is indeed included, as is target/src_managed/main.
After playing around with injecting debug prints, I found that the sbt-jflex plugin assumes sources are in src/main/flex whereas my project has them in src/main/jflex. Adding the following fixes it:
sourceDirectory in jflex <<= (sourceDirectory in Compile) { _ / "jflex" }

Resources