Maven and SCons as Buildsystem
Right now the whole concept is in an evaluation phase.
Idea and Background
Single Buildsystem, used by C/C++/Fortran and Java Projects. Exchange Build-Artifacts between projects. Less dependencies on environment variables. Possibility to build outside of central cluster. Possibility to compile from scratch.
Components
From the final product to the source code:
Final results are stored in an hierachical versioned artifact repository at
http://artifacts.acc.gsi.de/nexus.
The result of a maven build is (one or more) artifact. Basicly an artifact is an archive. For Java this is a jar, for native code we use a zip. Additionally an artifact has some metadata that describes it.
Every artifact can be referenced by its coordinates. Coordinates consist of a groupname (e.g. de.gsi.bel.something), artifactname (e.g. foobar), version (1.0.0), and packaging type.
TODO: the groupname will be de.gsi.cs.co.something in the future.
Artifacts can depend on each other. This is noted in the metadata.
Maven can manage these dependencies and interact with the artifact repository. For Java that is all that is needed, you can stop now.
As maven has no clue how to compile native code, there is the need for a plugin. For gsi there is a custom plugin that glues maven together with scons.
Using the maven-scons-plugin, maven is used to handle dependencies and repository interaction. Once maven prepared the environment for scons the compile process is handled by scons. The results are again packaged using maven.
Usage
The default GSI project layout (with maven-scons-plugin) looks like
project
+-- src
| +-- SConscript
| +-- *.cc
+- pom.xml
The file pom.xml describes the project to maven. The SConscript contains the actual build instructions for scons.
After a complete run the structure looks similar to this
project
+-- src
| +-- SConscript
| +-- *.cc
+-- target
| +-- build
| +-- install
| +-- tests
| +-- artifact-version.zip
+- pom.xml
Nothing is changed in the src folder. Compile steps and intermediate object files are all placed inside of
target/build
. Inside of
target/install
the final results (programs, libraries, headers) are collected. If any test programs are compiled they are placed in
target/tests
. The final artifact is packaged as zip-file in the target folder.
Maven
A preconfigured version of maven is installed in the cluster. It can be called using
mvn
. The preconfigured version of maven automatically uses the GSI artifact repository.
mvn clean
will delete the target folder.
mvn generate-sources
will fetch the dependencies and prepare everything for scons
mvn compile
will execute the actual compile run (leaving out the test programs)
mvn test-compile
will compile all test programs
mvn test
will run the test programs
mvn package
creates the archive
mvn install
will install the resulting archive in your personal repository. Ready to use for all projects you compile
mvn deploy
will deploy your artifact to artifacts.acc.gsi.de. Ready to use by everyone. Once an artifact is deployed you can't overwrite it. You need to deploy a new version.
Except the clean phase, all phases are dependent. So running
mvn install
will run through generate-sources, compile, test-compile, test, package and install.
Scons
scons is installed system-wide for the cluster. If you want to compile somewhere else you need a scons 2.x version.
There is no need to call scons manually, however after running a
mvn generate-soures
everything is prepared for it. Change to the target directory and there you can run
scons
compile default
scons test-compile
compile the test programs
SConscript files are python code. So watch out for line indentation and whitespace. The sample file below should help you get started.
Sample for pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<!--
get default settings like repository, plugin versions,
scm, bugtracker, etc
-->
<parent>
<groupId>de.gsi.bel</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
</parent>
<groupId>de.gsi.bel. ...</groupId>
<artifactId>...</artifactId>
<version>1.0.0</version>
<packaging>scons</packaging>
<!--
known build architectures are amd64, i386, ppc
-->
<properties>
<scons.arch>amd64</scons.arch>
</properties>
<!--
sample dependency on google test framework
shows the usage of a variable, and the usage
of a version range.
This will automatically add include paths and libraries
to the scons build.
-->
<dependencies>
<dependency>
<groupId>de.gsi.bel.thirdparty</groupId>
<artifactId>googletest_${scons.arch}</artifactId>
<version>[0,]</version>
<type>zip</type>
</dependency>
</dependencies>
<!--
activate the scons plugin
the plugin version and configuration is in the parent
-->
<build>
<plugins>
<plugin>
<groupId>de.gsi.bel.maven.plugins</groupId>
<artifactId>scons-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Sample for SConscript
Import('env') # get the preconfigured environment
hello = env.Program('helloworld', ['helloWorld.cc'])
env.InstallBin(hello)
## other builders beside Program
# env.StaticLibrary, env.SharedLibrary
## other installers beside bin
# env.InstallHeader, env.InstallLib
## link with an additional library
# env.AppendUnique(LIBS="pthread")
###
### TESTS
###
test1 = env.Program('gtest_foo', ['tests/helloWorld_unitTest.cc', 'helloWorld.cc'])
env.InstallTest(test1)
--
ChristophHandel - 29 Nov 2011