Fork me on GitHub

Introduction

NOTE: bold print is NOT implemented yet.

This plugin for Maven 2 allows you to compile native code (c++, c and fortran) on a number of different architectures (Linux, Windows, MacOSX, Solaris, ...) and with a number of different compilers/linkers (g++, Microsoft Visual C++, CC, ...) The output produced is wrapped up in Native ARchive files (.nar) some of which are machine independent (-noarch), while others are machine specific and thus depend on a combination of machine architecture(A), operating-system(O) and linker(L) identified as AOL. These nar files can be installed in the local maven repository and deployed to a standard maven (web) server, using the standard maven-install-plugin and maven-deploy-plugin.

Other maven projects may specify dependencies on these nar files using the standard maven dependency declaration. Nar files get downloaded, unpacked and installed in the local maven repository, just like jar files are (apart from the unpacking).

The NAR plugin executes the following goals, in the order below, to create and deploy nar files. The goals are part of the nar packaging/lifecycle, which inserts the nar goals into the standard lifecyle. Using nar packaging allows you to build a jar file as well as nar files. The list below shows the sequence of the NAR goals:

  1. nar-validate
  2. nar-download
  3. nar-unpack
  4. nar-gnu-configure
  5. nar-system-generate
  6. nar-resources
  7. nar-gnu-resources
  8. nar-javah
  9. nar-gnu-make
  10. nar-compile
  11. nar-gnu-process
  12. nar-test-unpack
  13. nar-testCompile
  14. nar-test
  15. nar-package
  16. nar-integration-test
  17. install (standard maven goal)
  18. deploy (standard maven goal)

Initialization

The NAR Plugin starts off by setting and deducing all kinds of property values for usage in the goals below. The configuration section of the NAR plugin allows one to override most of the default settings. The default settings come from the AOL properties file which allows us to specify different defaults depending on the architecture-os-linker combination, see AOL Properties.

The NAR Plugin tries to deduce the "Operating System" and the "Architecture" of the machine. Both can be overridden by setting os and arch in the configuration.

The name of the linker is looked up in an architecture-os specific way, but can be overridden by setting linker.name (this means the subtag <name> of the <linker> tag in the configuration section). Now that the linker name is known all other properties are looked up with a prefix of [arch.[os.[linker.]]] from the AOL Properties file, but can be overridden in the configuration section (which can be made AOL specific by putting it inside a profile).

nar-validate

The NAR plugin makes sure the linker name can be found and that at least one compiler exists for this linker. It further checks the version number of the linker to see if the linker is actually found on the path.

nar-download

Your NAR artifact(s) may be dependent on other nar artifacts. The standard maven dependency declaration in the POM is used to describe such dependencies of type "nar", see NAR dependencies. By the time this goal is running maven will have already downloaded all dependent jar and nar files some of which may include a nar.properties file. This property file contains information on what other machine dependent and machine independent nar files to download. This goal will download any further necessary nar files into the local repository.

nar-unpack

Since a nar file is of no use to any native compilation process, the nar-unpack goal unpacks the nar into the "nar" subdirectory of the target directory. The dependencies taken in account are those with the scopes compile, provided and system which are the scopes needed for compilation.

nar-gnu-configure

If you store files in the gnuSourceDirectory (src/gnu) the NAR plugin will try to run autogen and configure over them with a target set to gnuTargetDirectory. This process can be disabled by setting gnuAutogenSkip and or gnuConfigureSkip. On Windows, this process will only run if gnuUseOnWindows is set. The generated and configured files are all stored in gnuTargetDirectory and will be handled in subsequent NAR goals.

nar-system-generate

This goal generates a NarSystem class if necessary. This class contains helper methods for your code to handle things at run-time. The static method "loadLibrary()" is currently the only method generated and will load your JNI library with name "artifactId-version". This goal is only executed if you produce a JNI library and you specify a narSystemPackage as subtag of library. The NarSystem class will then be created in this package.

nar-resources

This is an optional goal. It will take any resources in src/nar/resources and copy them into specific areas under target/nar. Resources may include pre-compiled/linked libraries and other shareable items. This goal can be used to create a nar library from a distribution that comes with compiled shareable libraries.

nar-gnu-resources

Copies the resourceIncludeDir (include) from the gunSourceDirectory (src/gnu) into the noarch area in the target directory.

nar-javah

This goal will run the javah tool on any class file in the javah.classDirectory directory that has native methods in it. The actual class files are inspected (rather than their sources). The javah tool is picked up from the java installation and is run with a classpath of the javah.classDirectory and all depencies' classpaths, unless you specify a list in javah.classPaths. Additional classnames like java.sql.Types, which have no actual *.class file in the classDirectory, can be added using the javah.extraClasses list. You can also set a boot classpath using javah.bootClassPaths.

This goal has no effect if there are no java sources, or if none of the java classes contain a native method.

nar-gnu-make

Runs "make" followed by "make install" to put the final files in position for copying to the NAR target areas by the nar-gnu-process goal.

nar-compile

This goal will compile the native source code (c, c++ or fortran) and archive it into a shared library. You can also produce a jni or a static library by setting library.type. To handle the variety of compilers and linkers, the NAR plugin uses a derivative of the cpptasks from the ant-contrib project, with some minor improvements and additions of compilers. Most of the settings for cpptasks, such as compiler, linker, options and include dirs are available through the NAR plugin, see configuration.

The NAR plugin searches the directory structure under COMPILER.sourceDirectory, which defaults to src/main. The standard way to separate your sources for different languages would be src/main/c, src/main/c++ and src/main/fortran, but any file under src/main is searched for.

The nar plugin will automatically select the correct compiler (c, c++ or fortran) based on the type of source, as specified in the patterns in AOL.c.includes, AOL.cpp.includes and AOL.fortran.includes, where AOL is a dotted qualifier of the architecture, os and linker (x86.Windows.msvc for example).

Include paths are added in this order from:

  • any directories set in COMPILER.includePaths, where COMPILER is c, cpp or fortran.
  • the javah.jniDirectory.
  • if java.include is true or if javah.jniDirectory exists we add one of the following, relative to the java home directory:
    • java.includePaths if set,
    • otherwise the AOL.java.include property from the AOL properties.
  • the header files of any of the nar type dependencies, unless it is a jni library.
  • any system directories set in COMPILER.sysincludepath, where COMPILER is c, cpp or fortran.

The static or dynamic library is linked against:

  • the list of libraries set in linker.libs. Using nar dependencies is preferred though.
  • the libraries of any of the nar type dependencies.
  • the java virtual machine if you set java.link to true. The location of the runtime can be overridden in java.runtimeDirectory.

All include files from COMPILER.includePaths are copied to be included in the noarch nar file.

TBD If you set maven.nar.includefilesonly to true the compilation step will be skipped. This flag can be used if you want to distribute a library that only contains pure abstract classes in include files.

nar-gnu-process

Copies the gnu "install"-ed area into the NAR target area for testing and packing.

nar-test-unpack

Unpacks the nar dependencies into the "test-nar" subdirectory of the target directory. The dependencies taken in account are those with the scopes compile, provided, runtime, system and test which are the scopes needed for tests compilation and executions.

nar-testCompile

This goal will compile the native test source code (c, c++ or fortran) and create executables from it. To handle the variety of compilers and linkers, the NAR plugin uses a derivative of the cpptasks from the ant-contrib project, with some minor improvements and additions of compilers. Most of the settings for cpptasks, such as compiler, linker, options and include dirs are available through the NAR plugin, see configuration.

The NAR plugin searches the directory structure under COMPILER.sourceDirectory, which defaults to src/test. The standard way to separate your sources for different languages would be src/test/c, src/test/c++ and src/test/fortran, but any file under src/test is searched for.

The compiler will automatically select the correct compiler (c, c++ or fortran) based on the type of sources, as specified in the patterns in AOL.c.includes, AOL.nar.src.includes and AOL.fortran.includes, where AOL is a dotted qualifier of the architecture, os and linker (x86.Windows.msvc for example).

TBD If you set maven.nar.includefilesonly to true the compile-tests goal will be skipped.

nar-test

Runs any native tests as well as any executables that have been produced.

nar-package

This goal creates the artifact jar/nar file(s). The jar file is created by the standard package goal. The following jar and nar files are created:

  • <Artifact>-<version>.jar, containing a property file describing the behaviour of the library and other nar files available. For a description see NAR dependencies. This jar file is renamed to nar when installed or deployed.
  • <Artifact>-<version>-noarch.nar, a compressed jar file containing non machine specific parts of the distribution, such as the include directories.
  • <Artifact>-<version>-<aol>-<type>.nar, a compressed jar file containing machine specific parts of the distribution, such as the libraries. This file is specific to a particular Architecture-OS-Linker (AOL) combination TBD and is not generated if maven.nar.includefilesonly is set. Type specifies if this nar is either of type shared, static or jni.

nar-integration-test

This goal runs tests against the packaged jar and nar files. Currently this is useful only to test a jni library. The jni library is added to the java.library.path and the tests are forked to pick up this path.

To use this goal you need to put the test sources in the regular test directories but disable the running of the tests by the maven-surefire-plugin.

TBD integration tests for other types of libraries than jni

install

This goal installs the produced artifacts in your local repository. The unpacking is done in the unpack goal of a dependent artifact upon first usage.

deploy

This goal deploys the produced artifacts on a maven (web) server. The jar and nar files will always be in their packaged form on the server (they will never be unpacked there by maven).