Building Artifacts
When the program works, we can build something we can ship: Java class files, a JAR-file, a standalone fat JAR-file, or a Flix package.
Two of these are what we usually want: a fat JAR-file, if we distribute a program to end users, since it runs on its own wherever Java runs, and a Flix package, if we share a library with other Flix developers.
Compiling the Project
We can compile the project with the build command. The build command compiles
the entire project, including code generation, but writes nothing to disk. We use
it to check that the whole project compiles.
Building Class Files
We can compile the project to Java class files with the build-classes command.
Flix writes the class files to the build/class directory, and if the project has
a main function, we can run it with java:
$ java -cp build/class Main
Hello World!
Class files are rarely what we want to ship: we have to keep the directory together, and we have to put every dependency on the class path ourselves. To hand the program to someone else, we build a fat JAR-file instead.
Note: If the project, or one of its dependencies, depends on JAR-files, then these must also be on the class path.
Building a JAR-file
We can build a JAR-file with the build-jar command. Flix writes the JAR-file to the
artifact directory, named after the project directory — a project in a directory
called hello-world gives us artifact/hello-world.jar — and we can run it with
java:
$ java -jar artifact/hello-world.jar
Hello World!
The JAR-file holds the class files of the project together with the files in the
resources directory, if the project has one.
Note: The
build-jarcommand compiles the project itself. There is no need to runbuildorbuild-classesfirst.
A JAR-file built this way does not hold the dependencies of the project. If the program uses one — say a Java library, as described in Using Dependencies — then the JVM fails to find it when we run the JAR-file:
$ java -jar artifact/inventory.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
We can either put the dependencies on the class path ourselves, or bundle them into the JAR-file.
Bundling Dependencies in a Fat JAR-file
We can build a JAR-file with all dependencies bundled — a fat JAR-file — with
the build-fatjar command. Flix writes it to the same place, and now the program
runs on its own:
$ java -jar artifact/inventory.jar
!dlroW olleH
The fat JAR-file holds the class files of the project, the files in the resources
directory, and the contents of every JAR-file the project depends on, i.e. all
dependencies — both Flix and Maven.
Note: The
build-jarandbuild-fatjarcommands write to the same JAR-file. Whichever we ran last is the one we have.
Note: The
build-fatjarcommand compiles the project itself. There is no need to runbuildorbuild-classesfirst.
Building a Flix Package
We can bundle the project into a Flix package with the build-pkg command. Flix
writes the package to the artifact directory, and copies the manifest next to it:
artifact
├── flix.toml
└── package.fpkg
These two files are exactly what a release holds, and exactly what the release
command uploads, as described in Publishing a Package.
Both carry a fixed name: the package is called package.fpkg whatever the project is
called and wherever it is built, so that the files of a release can be addressed from
the repository and the version alone, without reading anything first.
Note: JAR-files do not follow this rule: a JAR-file is a local build output that nothing fetches by address, so
build-jarandbuild-fatjarkeep naming it after the project directory. In a project directory calledhello-world, theartifactdirectory therefore holdspackage.fpkg,flix.toml, andhello-world.jar.
A Flix package is essentially a zip-file of the source code of the project: it
holds the manifest, the README.md, the LICENSE.md, and the Flix files in src.
It holds no tests and no compiled code — a Flix package is compiled from source by
whoever depends on it. Together with its manifest, it can be published on GitHub,
as described in Publishing a Package.
Note: The
build-pkgcommand checks the project first, and refuses to build a package from source code that does not compile.
Note: The
build-pkgcommand requires a manifest, since a package without a manifest cannot be published.
Cleaning Up
We can remove the build and artifact directories with the clean command.
This deletes the class files written by build-classes, the documentation written
by doc, and the JAR- and package-files written by build-jar, build-fatjar,
and build-pkg.