Problem

Clojure today exists at a balance point between performance and dynamic flexibility. Some users would be willing to sacrifice dynamic features to gain more performance. Other users would be willing to sacrifice performance to gain better development error messages or debugging. The problem we aim to solve is to alter the Clojure build such that we can produce alternate versions of Clojure that are useful to smaller audiences while retaining Clojure as it is today.

Example builds we may want to produce (examples, not finalized):

"default" build - the current build that most people should use

"dev" build

More detailed error messages that would affect performance if included in default build

No locals clearing or other features to aid in debugging

Other features that may aid in development but affect performance

"fast" build

Specialized features that give up some Clojure features (ability to redef) in exchange for performance (truly static vars)

"experimental" build

A place to provide experimental compiler features that we want users to evaluate for the default build

Constraints

Clojure users:

Build profile artifacts should be available in public Maven repositories for use with existing build systems (Leiningen, Maven)

Some features may require further compiler flags or metadata to activate even if using the specialized build

For example, you may need to supply ^:static metadata on a function to get access to this feature

Ideally, use of the special feature should be simply ignored if not using the specialized build (or a warning should direct you)

Build:

Produce multiple output jars each time we build a version (snapshot or release)

The jars will contain different versions of the classes

Specialized build flags or env variables will need to be set during the build for each variant

Integration / release infrastructure:

Hudson CI server must be able to build and test custom builds as part of the dependency matrix

Hudson CI server must be able to perform releases for all of the variants

Compiler:

The compiler will need a standard way to determine which variant is active to make decisions during compilation.

Research

Maven coordinate options

Different artifactId

Releasing different artifacts would probably require running the build multiple times - there are probably some complexities in the CI and release process as a result.

Different qualifier

Qualifiers are really designed to give you more information about the purpose of a released version (alpha, beta, GA, build number), so this would be departing from standard Maven expectations.

Different classifier

Classifiers are designed for this use case - they allow you to create variants of the same group/artifact/version specialized for a particular environment (JDK variants is one example they use)

Lein and Maven can both specify a classifier - in lein with [org.clojure/clojure "1.6.0" :classifier "foo"]

It seems good that the main build and variant share Maven co-ords - there is then a standard way to get from main artifact to (for example) the dev variant for tooling.

Maven custom assembly

The Maven assembly plugin allows for arbitrary customization of the artifacts created by the build. However, creating multiple artifacts with different Maven coordinates will likely require multiple builds to produce each artifact for deployment.