Generating Java Sources with sbt JFlex plugin - sbt

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" }

Related

QtTest: prevent executable from being copied to system

So, there I'm writing some library and desided to have a proper unit-testing for it (like TDD and so on). QtTest framework looked suitable to start with. The library itself is fine, so is the test.
But when I added both the library and the test project to my job project, CI build surprisingly failed. It occured that the test executable (LibraryTest.exe or similar on Linux) was being copied:
to %QTDIR%/tests in a separate folder on Windows
to /usr/tests on Linux
My test project settings added this behavior to the "install" build stage, there they are (important ones):
QT += core testlib
# The problem is below
CONFIG += c++11 qt warn_on depend_includepath #testcase
CONFIG -= app_bundle
LIBS *= -L$$PWD -lmylibrary # not exact, does not matter
TARGET = LibraryTest
SOURCES += \
tst_my_library_test.cpp
DEFINES *= QT_FORCE_ASSERTS
DESTDIR = $$PWD/bin
As you can see, after commenting out CONFIG += testcase the executable is not copied somewhere anymore. I've read that this configuration option is used for automated tests, that looks useful, but nothing is written about any special install stage. The test executable exists in the DESTDIR just fine, so it is not some accident error.
My question is: why is it happening? Can I specify some other folder?
Automation is usefull, but even if implemented it would be probably bound to some more convenient directory.
Am I cooking the QtTest wrong? Thanks in advance for your attention.
Okay, after hacking the tests in my own way and getting enough time to study the problem thoroughly it occured that Qt's tests are designed to be used in a quite another way than I've thought.
It was obvious, that the testcase's makefile differs from the regular one, but the official documentation just stated the following:
For testcase projects, qmake will insert a check target into the generated Makefile. This target will run the application. The test is considered to pass if it terminates with an exit code equal to zero.
This gave a hint, what exactly resulted in makefile having extra install_target: first FORCE with strange and wrong file copying, but didn't explain the behavior deeper.
After some more seraching I found the following here:
Note also that Qt tests have only been tested with a non-installing Qt (the -prefix $PWD option above). The test project files override the make install target, so they are not installable. And Qt doesn't work at all if it's not at its installation path.
As far as my project uses heavilly the install build step and the tests were part of the project tree, it explained the problem.

sbt global plugins fail to load sometimes

I'm having problems with global plugins every once in a while, especially when I checkout another branch of my project from git. I installed sbt-dependency-graph as per their readme as a global plugin. global.sbt has a line
net.virtualvoid.sbt.graph.Plugin.graphSettings
and I am getting this annoying java.lang.NoClassDefFoundError: net/virtualvoid/sbt/graph/Plugin$ error even when I just run sbt in my project root. We also have a global plugin in a form of scala file in ~/.sbt/0.13, sometimes it causes problems as well. I haven't picked up the pattern yet.
you should install the sbt-dependency-graph plugin
step 1:
vim ~/.sbt/0.13/plugins/plugins.sbt
input:
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.5")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
step 2:
vim ~/.sbt/0.13/global.sbt
input:
net.virtualvoid.sbt.graph.Plugin.graphSettings
now you can use dependency-graph:
sbt dependency-graph
This happened to me, and the cause was the project I had open depended on a newer and incompatible version of sbt-dependency-graph. SBT decided to put the newer on in the classpath, and so the line in my global.sbt file didn't work anymore.

Getting JavaCV 0.9 platform binaries to download automatically with 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")

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'

Passing JVM args through sbt

I'm trying to add a 3rd party jar to my java library path. If I invoke sbt with -Djava.library.path=a-3rd-party-lib.jar, then it works for the first invocation of run-main MyClass inside sbt, but thereafter the 3rd party code complains that the jar is not in the java library path. I have also tried adding javaOptions += "-Djava.library.path=a-3rd-party-lib.jar" to my build.sbt file, but this hasn't worked (even for the first run). Qualifying this command as javaOptions in (Test,run) += "-Djava.library.path=a-3rd-party-lib.jar" (as seen in the docs) hasn't worked either.
Am I doing something wrong, or is this a strange bug?
FYI I'm using sbt 0.13.0
javaOptions only takes effect if you fork run and sbt does not fork by default. See the Forking documentation for details, but forking is enabled for run and runMain with:
fork in run := true

Resources