Skip to end of metadata
Go to start of metadata

Many applications of Maven require the use of artifact variants (i.e. the same version of an artifact built in different ways). Examples are the Native Mojo discussionSupport for other languages, which requires different variants for architecture/operating system/system (AOS), etc. Another example is a debug, release or obfuscated build of a jar. I don't think these variants can be defined in advance, because Maven cannot anticipate the possible variants people will want to produce. Also, in native land, a mere AOS will not suffice, since a library can be built with or without zlib/png/jpeg/whatever support. In addition, it should be possible to define alternatives if a variant is missing: If there's no debug build in the repo, Maven should be able to automatically use the normal one, or if there's no library optimized for the core2 processor, Maven should automatically use the i686 version.

Therefor this proposal is for Maven to support a generic and flexible variant system, inspired by Gentoo's USE variables. A project would declare a variant section in its pom, specifying what variants are available, e.g.

<variant>
    <option>
        <name>arch</name>
        <description>System architecture</description>
        <default>i386</default>
        <optionValues>
            <optionValue>
                <value>i386</value>
                <description>Generic i386 processor</description>
            </optionValue>
            <optionValue>
                <value>i686</value>
                <description>Generic i686 processor</description>
                <alternatives>i386</alternatives>
            </optionValue>
        </optionsValues>
    </option>
    <option>
        <name>build</name>
        <description>Build type</description>
        <optional>true</optional>
        <optionValues>
            <optionValue>
                <value>debug</value>
                <description>Include debug information</description>
            </optionValue>
            <optionValue>
                <value>obfuscated</value>
                <description>Obfuscate the code</description>
            </optionValue>
        </optionValues>
    </option>
</variant>

Option names and values should be unique within a project (no option value "debug" can be used in other options than "build" in the example). A project would also specify (e.g. via profiles) which variant is active, on a global and on a per-dependency scale:

<use>
    <option>
        <name>arch</name>
        <value>i686</value>
    </option>
    <option>
        <name>build</name>
        <value>debug</value>
    </option>
</use>

When resolving artifacts, Maven checks if all required options are specified, and their values are valid. It then builds a variant specifier ("i686-debug") and uses this to resolve the artifact. I'm not sure if the classifier should be used for this, or if an additional field should be introduced, though. If an optional option (smile) is missing, it is omitted from the specifier (i.e. if "build" were unspecified in the example, the variant specifier would be "i686"). Also, if the artifact cannot be found with the variant specifier, maven tries omitting optional options. In the example, if the "i686-debug" variant is not present, we try the "i686" variant. It also tries to use alternatives, so in the example, we would also try "i386-debug" and "i386". There should be a well defined order, of course, in which the variants are tried.

  • No labels