Building from Source

A complete build of flow involves two parts

  1. Building Scala sources (the front-end), resulting in a platform independent artifact (i.e. a jar file).

  2. Building C sources (the back-end), yielding a native library that may only be used on systems resembling the platform for which it was compiled.

Both steps are independent, their only interaction being a header file generated by the JDK utility javah (see sbt javah for details), and may therefore be built in any order.

Building Scala Sources

Run sbt flow-main/packageBin in the base directory. This simply compiles Scala sources as with any standard sbt project and packages the resulting class files in a jar.

Building Native Sources

The back-end is managed by GNU Autotools and all relevant files are contained in flow-native.

Build Process

Several steps are involved in producing the native library:

  1. Bootstrap the build (run this once, if ./configure does not exist).

    1. Check availability of dependencies: autotools and libtool (on Debian-based systems run apt-get install build-essential autoconf automake libtool)
    2. Run ./bootstrap
  2. Compile

    1. Check availability of dependencies: C compiler and JDK (1.8 or above)
    2. Run ./configure && make. Note: should you encounter an error about a missing “jni.h” file, try setting the JAVA_HOME environment variable to point to base path of your JDK installation.
  3. Install

    The native library is now ready and can be:

    • copied to a local directory: DESTDIR=$(pwd)/<directory> make install

    • installed system-wide: make install

    • put into a “fat” jar, useful for dependency management with SBT (see next section)

Creating a Fat Jar

The native library produced in the previous step may be bundled into a “fat” jar so that it can be included in SBT projects through its regular dependency mechanisms. In this process, sbt basically acts as a wrapper script around Autotools, calling the native build process and packaging generated libraries. Running sbt flow-native/packageBin in the base directory produces the fat jar in flow-native/target.

Note: an important feature of fat jars is to include native libraries for several platforms. To copy binaries compiled on other platforms to the fat jar, place them in a subfolder of flow-native/lib_native. The subfolder should have the name $(arch)-$(kernel), where arch and kernel are, respectively, the lower-case values returned by uname -m and uname -s.

Note About Versioning

The project and package versions follow a semantic pattern: M.m.p, where

Usually (following most Linux distribution’s conventions), shared libraries produced by a project name of version M.m.p are named libname.so.M.m.p. However, since when accessing shared libraries through the JVM, only the name can be specified and no particular version, the convention adopted by flow is to append M to the library name and always keep the major version at zero. E.g. libflow.so.3.1.2 becomes libflow3.so.0.1.2.

Publishing and Releasing

The release process managed with the sbt-release plugin. See ‘project/Release.scala’ for a description of the various steps involved.

Here are some important notes on creating a release: