diff options
author | Mark Donszelmann <Mark.Donszelmann@gmail.com> | 2009-10-01 14:33:24 +0200 |
---|---|---|
committer | Mark Donszelmann <Mark.Donszelmann@gmail.com> | 2009-10-01 14:33:24 +0200 |
commit | 846700d44b67b22835b57a1c04f17043db8323a3 (patch) | |
tree | a253ecd4ada6f80dbcd08177035cfa71ade9b670 | |
parent | 0a8746644d70eb8b1cfb615c27155c19e09f46d3 (diff) | |
download | maven-nar-plugin-846700d44b67b22835b57a1c04f17043db8323a3.tar.gz maven-nar-plugin-846700d44b67b22835b57a1c04f17043db8323a3.tar.bz2 maven-nar-plugin-846700d44b67b22835b57a1c04f17043db8323a3.tar.xz maven-nar-plugin-846700d44b67b22835b57a1c04f17043db8323a3.zip |
Moved files in from freehep-nar-plugin version 2.0-alpha-11-SNAPSHOT
57 files changed, 9037 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f0382d --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.classpath +.project +.settings +target + @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <parent> + <artifactId>maven-plugin-pom</artifactId> + <groupId>org.freehep</groupId> + <version>5</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <packaging>maven-plugin</packaging> + <name>FreeHEP Maven Native Archive Plugin</name> + <version>2.0-alpha-11-SNAPSHOT</version> + <description>Native Archive Plug-in to compile and link c++, c and fortran (for Maven 2), + see Introduction</description> + <repositories> + <repository> + <id>freehep-maven</id> + <name>Maven FreeHEP</name> + <url>http://java.freehep.org/maven2</url> + </repository> + </repositories> + <dependencies> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-compiler-api</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>1.2</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-archiver</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-booter</artifactId> + <version>2.3</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>net.sf.antcontrib</groupId> + <artifactId>cpptasks</artifactId> + <version>1.0-beta-4-parallel-3-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>bcel</groupId> + <artifactId>bcel</artifactId> + </dependency> + <dependency> + <groupId>ant</groupId> + <artifactId>ant</artifactId> + <version>1.6.5</version> + </dependency> + </dependencies> +</project> + diff --git a/src/main/java/org/apache/maven/plugin/nar/AOL.java b/src/main/java/org/apache/maven/plugin/nar/AOL.java new file mode 100644 index 0000000..3ae10c3 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/AOL.java @@ -0,0 +1,49 @@ +// Copyright FreeHEP, 2007. +package org.freehep.maven.nar; + +public class AOL { + + private String architecture; + private String os; + private String linkerName; + + // FIXME, need more complicated parsing for numbers as part of os. + public AOL(String aol) { + String[] aolString = aol.split("-", 3); + switch (aolString.length) { + case 3: + linkerName = aolString[2]; + case 2: + os = aolString[1]; + case 1: + architecture = aolString[0]; + break; + + default: + throw new RuntimeException("AOL '"+aol+"' cannot be parsed."); + } + } + + public AOL(String architecture, String os, String linkerName) { + this.architecture = architecture; + this.os = os; + this.linkerName = linkerName; + } + + public String toString() { + return architecture + + ((os == null) ? "" : "-" + os + + ((linkerName == null) ? "" : "-" + linkerName)); + } + + // FIXME, maybe change to something like isCompatible (AOL). + public boolean hasLinker(String linker) { + return linkerName.equals(linker); + } + + public String getKey() { + return architecture + + ((os == null) ? "" : "." + os + + ((linkerName == null) ? "" : "." + linkerName)); + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/AbstractCompileMojo.java b/src/main/java/org/apache/maven/plugin/nar/AbstractCompileMojo.java new file mode 100644 index 0000000..0a38229 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/AbstractCompileMojo.java @@ -0,0 +1,208 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +import org.apache.tools.ant.Project; + +/** + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/AbstractCompileMojo.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public abstract class AbstractCompileMojo extends AbstractDependencyMojo { + + /** + * C++ Compiler + * + * @parameter expression="" + */ + private Cpp cpp; + + /** + * C Compiler + * + * @parameter expression="" + */ + private C c; + + /** + * Fortran Compiler + * + * @parameter expression="" + */ + private Fortran fortran; + + /** + * Maximum number of Cores/CPU's to use. 0 means unlimited. + * + * @parameter expression="" + */ + private int maxCores = 0; + + /** + * Name of the output + * + * @parameter expression="${project.artifactId}-${project.version}" + */ + private String output; + + /** + * Fail on compilation/linking error. + * + * @parameter expression="" default-value="true" + * @required + */ + private boolean failOnError; + + /** + * Sets the type of runtime library, possible values "dynamic", "static". + * + * @parameter expression="" default-value="dynamic" + * @required + */ + private String runtime; + + /** + * Set use of libtool. If set to true, the "libtool " will be prepended to the command line for compatible processors. + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean libtool; + + /** + * The home of the Java system. + * Defaults to a derived value from ${java.home} which is OS specific. + * + * @parameter expression="" + * @readonly + */ + private File javaHome; + + /** + * List of libraries to create + * + * @parameter expression="" + */ + private List libraries; + + /** + * List of tests to create + * + * @parameter expression="" + */ + private List tests; + + /** + * Javah info + * + * @parameter expression="" + */ + private Javah javah; + + /** + * Java info for includes and linking + * + * @parameter expression="" + */ + private Java java; + + private NarInfo narInfo; + + private List/*<String>*/ dependencyLibOrder; + + private Project antProject; + + protected Project getAntProject() { + if (antProject == null) { + // configure ant project + antProject = new Project(); + antProject.setName("NARProject"); + antProject.addBuildListener(new NarLogger(getLog())); + } + return antProject; + } + + protected C getC() { + if (c == null) c = new C(); + c.setAbstractCompileMojo(this); + return c; + } + + protected Cpp getCpp() { + if (cpp == null) cpp = new Cpp(); + cpp.setAbstractCompileMojo(this); + return cpp; + } + + protected Fortran getFortran() { + if (fortran == null) fortran = new Fortran(); + fortran.setAbstractCompileMojo(this); + return fortran; + } + + protected int getMaxCores(AOL aol) { + return getNarInfo().getProperty(aol, "maxCores", maxCores); + } + + protected boolean useLibtool(AOL aol) { + return getNarInfo().getProperty(aol, "libtool", libtool); + } + + protected boolean failOnError(AOL aol) { + return getNarInfo().getProperty(aol, "failOnError", failOnError); + } + + protected String getRuntime(AOL aol) { + return getNarInfo().getProperty(aol, "runtime", runtime); + } + + protected String getOutput(AOL aol) { + return getNarInfo().getProperty(aol, "output", output); + } + + protected File getJavaHome(AOL aol) { + // FIXME should be easier by specifying default... + return getNarInfo().getProperty(aol, "javaHome", NarUtil.getJavaHome(javaHome, getOS())); + } + + protected List getLibraries() { + if (libraries == null) libraries = Collections.EMPTY_LIST; + return libraries; + } + + protected List getTests() { + if (tests == null) tests = Collections.EMPTY_LIST; + return tests; + } + + protected Javah getJavah() { + if (javah == null) javah = new Javah(); + javah.setAbstractCompileMojo(this); + return javah; + } + + protected Java getJava() { + if (java == null) java = new Java(); + java.setAbstractCompileMojo(this); + return java; + } + + public void setDependencyLibOrder(List/*<String>*/ order) { + dependencyLibOrder = order; + } + + protected List/*<String>*/ getDependencyLibOrder() { + return dependencyLibOrder; + } + + protected NarInfo getNarInfo() { + if (narInfo == null) { + narInfo = new NarInfo(getMavenProject().getGroupId(), getMavenProject() + .getArtifactId(), getMavenProject().getVersion(), getLog()); + } + return narInfo; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/AbstractDependencyMojo.java b/src/main/java/org/apache/maven/plugin/nar/AbstractDependencyMojo.java new file mode 100644 index 0000000..784027d --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/AbstractDependencyMojo.java @@ -0,0 +1,27 @@ +// Copyright FreeHEP, 2005-2006. +package org.freehep.maven.nar; + +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.plugin.MojoFailureException; + +/** + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/AbstractDependencyMojo.java c867ab546be1 2007/07/05 21:26:30 duns $ + */ +public abstract class AbstractDependencyMojo extends AbstractNarMojo { + + /** + * @parameter expression="${localRepository}" + * @required + * @readonly + */ + private ArtifactRepository localRepository; + + protected ArtifactRepository getLocalRepository() { + return localRepository; + } + + protected NarManager getNarManager() throws MojoFailureException { + return new NarManager(getLog(), getLocalRepository(), getMavenProject(), getArchitecture(), getOS(), getLinker()); + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/AbstractNarMojo.java b/src/main/java/org/apache/maven/plugin/nar/AbstractNarMojo.java new file mode 100644 index 0000000..576f27d --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/AbstractNarMojo.java @@ -0,0 +1,129 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; + + +/** + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/AbstractNarMojo.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public abstract class AbstractNarMojo extends AbstractMojo implements NarConstants { + + /** + * Skip running of NAR plugins (any) altogether. + * + * @parameter expression="${nar.skip}" default-value="false" + */ + private boolean skip; + + /** + * The Architecture for the nar, + * Some choices are: "x86", "i386", "amd64", "ppc", "sparc", ... + * Defaults to a derived value from ${os.arch} + * + * @parameter expression="${os.arch}" + * @required + */ + private String architecture; + + /** + * The Operating System for the nar. + * Some choices are: "Windows", "Linux", "MacOSX", "SunOS", ... + * Defaults to a derived value from ${os.name} + * FIXME table missing + * + * @parameter expression="" + */ + private String os; + + /** + * Architecture-OS-Linker name. + * Defaults to: arch-os-linker. + * + * @parameter expression="" + */ + private String aol; + + /** + * Linker + * + * @parameter expression="" + */ + private Linker linker; + + /** + * @parameter expression="${project.build.directory}" + * @readonly + */ + private File outputDirectory; + + /** + * @parameter expression="${project.build.finalName}" + * @readonly + */ + private String finalName; + + /** + * Target directory for Nar file construction + * Defaults to "${project.build.directory}/nar" for "nar-compile" goal + * Defaults to "${project.build.directory}/test-nar" for "nar-testCompile" goal + * + * @parameter expression="" + */ + private File targetDirectory; + + /** + * @parameter expression="${project}" + * @readonly + * @required + */ + private MavenProject mavenProject; + + + protected boolean shouldSkip() { + return skip; + } + + protected String getArchitecture() { + architecture = NarUtil.getArchitecture(architecture); + return architecture; + } + + protected String getOS() { + os = NarUtil.getOS(os); + return os; + } + + protected AOL getAOL() throws MojoFailureException { + return NarUtil.getAOL(architecture, os, linker, aol); + } + + protected Linker getLinker() { + linker = NarUtil.getLinker(linker); + return linker; + } + + protected File getOutputDirectory() { + return outputDirectory; + } + + protected String getFinalName() { + return finalName; + } + + protected File getTargetDirectory() { + if (targetDirectory == null) { + targetDirectory = new File(mavenProject.getBuild().getDirectory(), "nar"); + } + return targetDirectory; + } + + protected MavenProject getMavenProject() { + return mavenProject; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/AttachedNarArtifact.java b/src/main/java/org/apache/maven/plugin/nar/AttachedNarArtifact.java new file mode 100644 index 0000000..cf6881d --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/AttachedNarArtifact.java @@ -0,0 +1,66 @@ +// Copyright 2005-2007, FreeHEP. +package org.freehep.maven.nar; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; + +/** + * NarArtifact with its own type, classifier and artifactHandler. + * + * @author Mark Donszelmann + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/AttachedNarArtifact.java 54f05023f537 2007/07/24 05:44:30 duns $ + */ +public class AttachedNarArtifact extends DefaultArtifact { + + public AttachedNarArtifact(String groupId, String artifactId, String version, String scope, + String type, String classifier, boolean optional) throws InvalidVersionSpecificationException { + super(groupId, artifactId, VersionRange.createFromVersionSpec(version), scope, + type, classifier, null, optional); + setArtifactHandler(new Handler(classifier)); + } + + public AttachedNarArtifact(Artifact parent, String type, String classifier) { + super(parent.getGroupId(), parent.getArtifactId(), parent.getVersionRange(), parent.getScope(), + type, classifier, null, parent.isOptional()); + setArtifactHandler(new Handler(classifier)); + } + + private class Handler implements ArtifactHandler { + private String classifier; + + Handler(String classifier) { + this.classifier = classifier; + } + + public String getExtension() { + return "nar"; + } + + public String getDirectory() { + return "nars"; + } + + public String getClassifier() { + return classifier; + } + + public String getPackaging() { + return "nar"; + } + + public boolean isIncludesDependencies() { + return false; + } + + public String getLanguage() { + return "native"; + } + + public boolean isAddedToClasspath() { + return false; + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/C.java b/src/main/java/org/apache/maven/plugin/nar/C.java new file mode 100644 index 0000000..7826874 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/C.java @@ -0,0 +1,18 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +/** + * C compiler tag + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/C.java 631dc18040bb 2007/07/17 14:21:11 duns $ + */ +public class C extends Compiler { + + public C() { + } + + public String getName() { + return "c"; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Compiler.java b/src/main/java/org/apache/maven/plugin/nar/Compiler.java new file mode 100644 index 0000000..6f5a44a --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Compiler.java @@ -0,0 +1,496 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.CompilerDef; +import net.sf.antcontrib.cpptasks.CompilerEnum; +import net.sf.antcontrib.cpptasks.OptimizationEnum; +import net.sf.antcontrib.cpptasks.types.CompilerArgument; +import net.sf.antcontrib.cpptasks.types.ConditionalFileSet; +import net.sf.antcontrib.cpptasks.types.DefineArgument; +import net.sf.antcontrib.cpptasks.types.DefineSet; + +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.StringUtils; + +/** + * Abstract Compiler class + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Compiler.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public abstract class Compiler { + + /** + * The name of the compiler Some choices are: "msvc", "g++", "gcc", "CC", + * "cc", "icc", "icpc", ... Default is Architecture-OS-Linker specific: + * FIXME: table missing + * + * @parameter expression="" + */ + private String name; + + /** + * Source directory for native files + * + * @parameter expression="${basedir}/src/main" + * @required + */ + private File sourceDirectory; + + /** + * Include patterns for sources + * + * @parameter expression="" + * @required + */ + private Set includes = new HashSet(); + + /** + * Exclude patterns for sources + * + * @parameter expression="" + * @required + */ + private Set excludes = new HashSet(); + + /** + * Compile with debug information. + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean debug = false; + + /** + * Enables generation of exception handling code. + * + * @parameter expression="" default-value="true" + * @required + */ + private boolean exceptions = true; + + /** + * Enables run-time type information. + * + * @parameter expression="" default-value="true" + * @required + */ + private boolean rtti = true; + + /** + * Sets optimization. Possible choices are: "none", "size", "minimal", + * "speed", "full", "aggressive", "extreme", "unsafe". + * + * @parameter expression="" default-value="none" + * @required + */ + private String optimize = "none"; + + /** + * Enables or disables generation of multi-threaded code. Default value: + * false, except on Windows. + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean multiThreaded = false; + + /** + * Defines + * + * @parameter expression="" + */ + private List defines; + + /** + * Defines for the compiler as a comma separated list of name[=value] pairs, where the value is optional. + * Will work in combination with <defines>. + * + * @parameter expression="" + */ + private String defineSet; + + /** + * Clears default defines + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean clearDefaultDefines; + + /** + * Undefines + * + * @parameter expression="" + */ + private List undefines; + + /** + * Undefines for the compiler as a comma separated list of name[=value] pairs where the value is optional. + * Will work in combination with <undefines>. + * + * @parameter expression="" + */ + private String undefineSet; + + /** + * Clears default undefines + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean clearDefaultUndefines; + + /** + * Include Paths. Defaults to "${sourceDirectory}/include" + * + * @parameter expression="" + */ + private List includePaths; + + /** + * System Include Paths, which are added at the end of all include paths + * + * @parameter expression="" + */ + private List systemIncludePaths; + + /** + * Additional options for the C++ compiler Defaults to + * Architecture-OS-Linker specific values. FIXME table missing + * + * @parameter expression="" + */ + private List options; + + /** + * Options for the compiler as a whitespace separated list. + * Will work in combination with <options>. + * + * @parameter expression="" + */ + private String optionSet; + + /** + * Clears default options + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean clearDefaultOptions; + + private AbstractCompileMojo mojo; + + protected Compiler() { + } + + public void setAbstractCompileMojo(AbstractCompileMojo mojo) { + this.mojo = mojo; + } + + public File getSourceDirectory() { + return getSourceDirectory("dummy"); + } + + protected File getSourceDirectory(String type) { + if (sourceDirectory == null) { + sourceDirectory = new File(mojo.getMavenProject().getBasedir(), + "src/" + (type.equals("test") ? "test" : "main")); + } + return sourceDirectory; + } + + protected List/* <String> */getIncludePaths(String type) { + if (includePaths == null || (includePaths.size() == 0)) { + includePaths = new ArrayList(); + includePaths.add(new File(getSourceDirectory(type), "include") + .getPath()); + } + return includePaths; + } + + public Set getIncludes() throws MojoFailureException { + return getIncludes("main"); + } + + protected Set getIncludes(String type) throws MojoFailureException { + Set result = new HashSet(); + if (!type.equals("test") && !includes.isEmpty()) { + result.addAll(includes); + } else { + String defaultIncludes = NarUtil.getDefaults().getProperty( + getPrefix() + "includes"); + if (defaultIncludes == null) { + throw new MojoFailureException( + "NAR: Please specify <Includes> as part of <Cpp>, <C> or <Fortran> for " + + getPrefix()); + } + + String[] include = defaultIncludes.split(" "); + for (int i = 0; i < include.length; i++) { + result.add(include[i].trim()); + } + } + return result; + } + + protected Set getExcludes() throws MojoFailureException { + Set result = new HashSet(); + + // add all excludes + if (excludes.isEmpty()) { + String defaultExcludes = NarUtil.getDefaults().getProperty( + getPrefix() + "excludes"); + if (defaultExcludes != null) { + String[] exclude = defaultExcludes.split(" "); + for (int i = 0; i < exclude.length; i++) { + result.add(exclude[i].trim()); + } + } + } else { + result.addAll(excludes); + } + + return result; + } + + protected String getPrefix() throws MojoFailureException { + return mojo.getAOL().getKey() + "." + getName() + "."; + } + + public CompilerDef getCompiler(String type, String output) + throws MojoFailureException { + + // adjust default values + if (name == null) + name = NarUtil.getDefaults().getProperty(getPrefix() + "compiler"); + if (name == null) { + throw new MojoFailureException( + "NAR: Please specify <Name> as part of <Cpp>, <C> or <Fortran> for " + + getPrefix()); + } + + CompilerDef compiler = new CompilerDef(); + compiler.setProject(mojo.getAntProject()); + CompilerEnum compilerName = new CompilerEnum(); + compilerName.setValue(name); + compiler.setName(compilerName); + + // debug, exceptions, rtti, multiThreaded + compiler.setDebug(debug); + compiler.setExceptions(exceptions); + compiler.setRtti(rtti); + compiler.setMultithreaded(mojo.getOS().equals("Windows") ? true + : multiThreaded); + + // optimize + OptimizationEnum optimization = new OptimizationEnum(); + optimization.setValue(optimize); + compiler.setOptimize(optimization); + + // add options + if (options != null) { + for (Iterator i = options.iterator(); i.hasNext();) { + CompilerArgument arg = new CompilerArgument(); + arg.setValue((String) i.next()); + compiler.addConfiguredCompilerArg(arg); + } + } + + if (optionSet != null) { + + String[] opts = optionSet.split("\\s"); + + for (int i = 0; i < opts.length; i++) { + + CompilerArgument arg = new CompilerArgument(); + + arg.setValue(opts[i]); + compiler.addConfiguredCompilerArg(arg); + } + } + + if (!clearDefaultOptions) { + String optionsProperty = NarUtil.getDefaults().getProperty( + getPrefix() + "options"); + if (optionsProperty != null) { + String[] option = optionsProperty.split(" "); + for (int i = 0; i < option.length; i++) { + CompilerArgument arg = new CompilerArgument(); + arg.setValue(option[i]); + compiler.addConfiguredCompilerArg(arg); + } + } + } + + // add defines + if (defines != null) { + DefineSet defineSet = new DefineSet(); + for (Iterator i = defines.iterator(); i.hasNext();) { + DefineArgument define = new DefineArgument(); + String[] pair = ((String) i.next()).split("=", 2); + define.setName(pair[0]); + define.setValue(pair.length > 1 ? pair[1] : null); + defineSet.addDefine(define); + } + compiler.addConfiguredDefineset(defineSet); + } + + if (defineSet != null) { + + String[] defList = defineSet.split(","); + DefineSet defSet = new DefineSet(); + + for (int i = 0; i < defList.length; i++) { + + String[] pair = defList[i].trim().split("=", 2); + DefineArgument def = new DefineArgument(); + + def.setName(pair[0]); + def.setValue(pair.length > 1 ? pair[1] : null); + + defSet.addDefine(def); + } + + compiler.addConfiguredDefineset(defSet); + } + + if (!clearDefaultDefines) { + DefineSet defineSet = new DefineSet(); + String defaultDefines = NarUtil.getDefaults().getProperty( + getPrefix() + "defines"); + if (defaultDefines != null) { + defineSet + .setDefine(new CUtil.StringArrayBuilder(defaultDefines)); + } + compiler.addConfiguredDefineset(defineSet); + } + + // add undefines + if (undefines != null) { + DefineSet undefineSet = new DefineSet(); + for (Iterator i = undefines.iterator(); i.hasNext();) { + DefineArgument undefine = new DefineArgument(); + String[] pair = ((String) i.next()).split("=", 2); + undefine.setName(pair[0]); + undefine.setValue(pair.length > 1 ? pair[1] : null); + undefineSet.addUndefine(undefine); + } + compiler.addConfiguredDefineset(undefineSet); + } + + if (undefineSet != null) { + + String[] undefList = undefineSet.split(","); + DefineSet undefSet = new DefineSet(); + + for (int i = 0; i < undefList.length; i++) { + + String[] pair = undefList[i].trim().split("=", 2); + DefineArgument undef = new DefineArgument(); + + undef.setName(pair[0]); + undef.setValue(pair.length > 1 ? pair[1] : null); + + undefSet.addUndefine(undef); + } + + compiler.addConfiguredDefineset(undefSet); + } + + if (!clearDefaultUndefines) { + DefineSet undefineSet = new DefineSet(); + String defaultUndefines = NarUtil.getDefaults().getProperty( + getPrefix() + "undefines"); + if (defaultUndefines != null) { + undefineSet.setUndefine(new CUtil.StringArrayBuilder( + defaultUndefines)); + } + compiler.addConfiguredDefineset(undefineSet); + } + + // add include path + for (Iterator i = getIncludePaths(type).iterator(); i.hasNext();) { + String path = (String) i.next(); + compiler.createIncludePath().setPath(path); + } + + // add system include path (at the end) + if (systemIncludePaths != null) { + for (Iterator i = systemIncludePaths.iterator(); i.hasNext();) { + String path = (String) i.next(); + compiler.createSysIncludePath().setPath(path); + } + } + + // Add default fileset (if exists) + File srcDir = getSourceDirectory(type); + Set includes = getIncludes(); + Set excludes = getExcludes(); + + // now add all but the current test to the excludes + for (Iterator i = mojo.getTests().iterator(); i.hasNext();) { + Test test = (Test) i.next(); + if (!test.getName().equals(output)) { + excludes.add("**/" + test.getName() + ".*"); + } + } + + mojo.getLog().debug( + "Checking for existence of " + getName() + " sourceDirectory: " + + srcDir); + if (srcDir.exists()) { + ConditionalFileSet fileSet = new ConditionalFileSet(); + fileSet.setProject(mojo.getAntProject()); + fileSet.setIncludes(StringUtils.join(includes.iterator(), ",")); + fileSet.setExcludes(StringUtils.join(excludes.iterator(), ",")); + fileSet.setDir(srcDir); + compiler.addFileset(fileSet); + } + + // add other sources + if (!type.equals("test")) { + for (Iterator i = mojo.getMavenProject().getCompileSourceRoots() + .iterator(); i.hasNext();) { + File dir = new File((String) i.next()); + mojo.getLog().debug( + "Checking for existence of " + getName() + + " sourceCompileRoot: " + dir); + if (dir.exists()) { + ConditionalFileSet otherFileSet = new ConditionalFileSet(); + otherFileSet.setProject(mojo.getAntProject()); + otherFileSet.setIncludes(StringUtils.join(includes + .iterator(), ",")); + otherFileSet.setExcludes(StringUtils.join(excludes + .iterator(), ",")); + otherFileSet.setDir(dir); + compiler.addFileset(otherFileSet); + } + } + } + return compiler; + } + + protected abstract String getName(); + + public void copyIncludeFiles(MavenProject mavenProject, File targetDirectory) + throws IOException { + for (Iterator i = getIncludePaths("dummy").iterator(); i.hasNext();) { + File path = new File((String) i.next()); + if (path.exists()) { + NarUtil.copyDirectoryStructure(path, targetDirectory, null, + NarUtil.DEFAULT_EXCLUDES); + } + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Cpp.java b/src/main/java/org/apache/maven/plugin/nar/Cpp.java new file mode 100644 index 0000000..8b13b18 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Cpp.java @@ -0,0 +1,17 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +/** + * Cpp compiler tag + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Cpp.java 631dc18040bb 2007/07/17 14:21:11 duns $ + */ +public class Cpp extends Compiler { + public Cpp() { + } + + public String getName() { + return "cpp"; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Executable.java b/src/main/java/org/apache/maven/plugin/nar/Executable.java new file mode 100644 index 0000000..0762f64 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Executable.java @@ -0,0 +1,10 @@ +package org.freehep.maven.nar; + +import java.util.List; + +public interface Executable { + + public boolean shouldRun(); + + public List/*<String>*/ getArgs(); +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Fortran.java b/src/main/java/org/apache/maven/plugin/nar/Fortran.java new file mode 100644 index 0000000..033a94f --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Fortran.java @@ -0,0 +1,18 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +/** + * Fortran compiler tag + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Fortran.java 0c1f0fc112ac 2007/09/12 18:18:23 duns $ + */ +public class Fortran extends Compiler { + + public Fortran() { + } + + public String getName() { + return "fortran"; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Java.java b/src/main/java/org/apache/maven/plugin/nar/Java.java new file mode 100644 index 0000000..ac6d4c0 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Java.java @@ -0,0 +1,126 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.util.Iterator; +import java.util.List; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.types.CommandLineArgument; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LinkerArgument; + +import org.apache.maven.plugin.MojoFailureException; + +/** + * Java specifications for NAR + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Java.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public class Java { + + /** + * Add Java includes to includepath + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean include = false; + + /** + * Java Include Paths, relative to a derived ${java.home}. + * Defaults to: "${java.home}/include" and "${java.home}/include/<i>os-specific</i>". + * + * @parameter expression="" + */ + private List includePaths; + + /** + * Add Java Runtime to linker + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean link = false; + + /** + * Relative path from derived ${java.home} to the java runtime to link with + * Defaults to Architecture-OS-Linker specific value. + * FIXME table missing + * + * @parameter expression="" + */ + private String runtimeDirectory; + + /** + * Name of the runtime + * + * @parameter expression="" default-value="jvm" + */ + private String runtime = "jvm"; + + private AbstractCompileMojo mojo; + + public Java() { + } + + public void setAbstractCompileMojo(AbstractCompileMojo mojo) { + this.mojo = mojo; + } + + public void addIncludePaths(CCTask task, String outType) throws MojoFailureException { + if (include || mojo.getJavah().getJniDirectory().exists()) { + if (includePaths != null) { + for (Iterator i=includePaths.iterator(); i.hasNext(); ) { + String path = (String)i.next(); + task.createIncludePath().setPath(new File(mojo.getJavaHome(mojo.getAOL()), path).getPath()); + } + } else { + String prefix = mojo.getAOL().getKey()+".java."; + String includes = NarUtil.getDefaults().getProperty(prefix+"include"); + if (includes != null) { + String[] path = includes.split(";"); + for (int i=0; i<path.length; i++) { + task.createIncludePath().setPath(new File(mojo.getJavaHome(mojo.getAOL()), path[i]).getPath()); + } + } + } + } + } + + public void addRuntime(CCTask task, File javaHome, String os, String prefix) throws MojoFailureException { + if (link) { + if (os.equals(OS.MACOSX)) { + CommandLineArgument.LocationEnum end = new CommandLineArgument.LocationEnum(); + end.setValue("end"); + + // add as argument rather than library to avoid argument quoting + LinkerArgument framework = new LinkerArgument(); + framework.setValue("-framework"); + framework.setLocation(end); + task.addConfiguredLinkerArg(framework); + + LinkerArgument javavm = new LinkerArgument(); + javavm.setValue("JavaVM"); + javavm.setLocation(end); + task.addConfiguredLinkerArg(javavm); + } else { + if (runtimeDirectory == null) { + runtimeDirectory = NarUtil.getDefaults().getProperty(prefix+"runtimeDirectory"); + if (runtimeDirectory == null) { + throw new MojoFailureException("NAR: Please specify a <RuntimeDirectory> as part of <Java>"); + } + } + mojo.getLog().debug("Using Java Rumtime Directory: "+runtimeDirectory); + + LibrarySet libset = new LibrarySet(); + libset.setProject(mojo.getAntProject()); + libset.setLibs(new CUtil.StringArrayBuilder(runtime)); + libset.setDir(new File(javaHome, runtimeDirectory)); + task.addLibset(libset); + } + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Javah.java b/src/main/java/org/apache/maven/plugin/nar/Javah.java new file mode 100644 index 0000000..7141ab4 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Javah.java @@ -0,0 +1,237 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.bcel.classfile.ClassFormatException; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.Method; +import org.apache.maven.artifact.DependencyResolutionRequiredException; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.codehaus.plexus.compiler.util.scan.InclusionScanException; +import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner; +import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner; +import org.codehaus.plexus.compiler.util.scan.mapping.SingleTargetSourceMapping; +import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.StringUtils; + +/** + * Sets up the javah configuration + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Javah.java eeac31f37379 2007/07/24 04:02:00 duns $ + */ +public class Javah { + + /** + * Javah command to run. + * + * @parameter default-value="javah" + */ + private String name = "javah"; + + /** + * Add boot class paths. By default none. + * + * @parameter + */ + private List/*<File>*/ bootClassPaths = new ArrayList(); + + /** + * Add class paths. By default the classDirectory directory is included and all dependent classes. + * + * @parameter + */ + private List/*<File>*/ classPaths = new ArrayList(); + + /** + * The target directory into which to generate the output. + * + * @parameter expression="${project.build.directory}/nar/javah-include" + * @required + */ + private File jniDirectory; + + /** + * The class directory to scan for class files with native interfaces. + * + * @parameter expression="${project.build.directory}/classes" + * @required + */ + private File classDirectory; + + /** + * The set of files/patterns to include + * Defaults to "**\/*.class" + * + * @parameter + */ + private Set includes = new HashSet(); + + /** + * A list of exclusion filters. + * + * @parameter + */ + private Set excludes = new HashSet(); + + /** + * The granularity in milliseconds of the last modification + * date for testing whether a source needs recompilation + * + * @parameter default-value="0" + * @required + */ + private int staleMillis = 0; + + /** + * The directory to store the timestampfile for the processed aid files. Defaults to jniDirectory. + * + * @parameter + */ + private File timestampDirectory; + + /** + * The timestampfile for the processed class files. Defaults to name of javah. + * + * @parameter + */ + private File timestampFile; + + private AbstractCompileMojo mojo; + + public Javah() { + } + + public void setAbstractCompileMojo(AbstractCompileMojo mojo) { + this.mojo = mojo; + } + + protected List getClassPaths() throws MojoExecutionException { + if (classPaths.isEmpty()) { + try { + classPaths.addAll(mojo.getMavenProject().getCompileClasspathElements()); + } catch (DependencyResolutionRequiredException e) { + throw new MojoExecutionException("JAVAH, cannot get classpath", e); + } + } + return classPaths; + } + + protected File getJniDirectory() { + if (jniDirectory == null) { + jniDirectory = new File(mojo.getMavenProject().getBuild().getDirectory(), "nar/javah-include"); + } + return jniDirectory; + } + + protected File getClassDirectory() { + if (classDirectory == null) { + classDirectory = new File(mojo.getMavenProject().getBuild().getDirectory(), "classes"); + } + return classDirectory; + } + + protected Set getIncludes() { + if (includes.isEmpty()) { + includes.add("**/*.class"); + } + return includes; + } + + protected File getTimestampDirectory() { + if (timestampDirectory == null) { + timestampDirectory = getJniDirectory(); + } + return timestampDirectory; + } + + protected File getTimestampFile() { + if (timestampFile == null) { + timestampFile = new File(name); + } + return timestampFile; + } + + public void execute() throws MojoExecutionException, MojoFailureException { + getClassDirectory().mkdirs(); + + try { + SourceInclusionScanner scanner = new StaleSourceScanner(staleMillis, getIncludes(), excludes); + if (getTimestampDirectory().exists()) { + scanner.addSourceMapping(new SingleTargetSourceMapping( ".class", getTimestampFile().getPath() )); + } else { + scanner.addSourceMapping(new SuffixMapping( ".class", ".dummy" )); + } + + Set classes = scanner.getIncludedSources(getClassDirectory(), getTimestampDirectory()); + + if (!classes.isEmpty()) { + Set files = new HashSet(); + for (Iterator i=classes.iterator(); i.hasNext(); ) { + String file = ((File)i.next()).getPath(); + JavaClass clazz = NarUtil.getBcelClass(file); + Method[] method = clazz.getMethods(); + for (int j=0; j<method.length; j++) { + if (method[j].isNative()) files.add(clazz.getClassName()); + } + } + + if (!files.isEmpty()) { + getJniDirectory().mkdirs(); + getTimestampDirectory().mkdirs(); + + mojo.getLog().info( "Running "+name+" compiler on "+files.size()+" classes..."); + int result = NarUtil.runCommand(name, generateArgs(files), null, mojo.getLog()); + if (result != 0) { + throw new MojoFailureException(name+" failed with exit code "+result+" 0x"+Integer.toHexString(result)); + } + FileUtils.fileWrite(getTimestampDirectory()+"/"+getTimestampFile(), ""); + } + } + } catch (InclusionScanException e) { + throw new MojoExecutionException( "JAVAH: Class scanning failed", e ); + } catch (IOException e) { + throw new MojoExecutionException( "JAVAH: IO Exception", e ); + } catch (ClassFormatException e) { + throw new MojoExecutionException( "JAVAH: Class could not be inspected", e); + } + } + + private String[] generateArgs(Set/*<String>*/ classes) throws MojoExecutionException { + + List args = new ArrayList(); + + if (!bootClassPaths.isEmpty()) { + args.add("-bootclasspath"); + args.add(StringUtils.join(bootClassPaths.iterator(), File.pathSeparator)); + } + + args.add("-classpath"); + args.add(StringUtils.join(getClassPaths().iterator(), File.pathSeparator)); + + args.add("-d"); + args.add(getJniDirectory().getPath()); + + if (mojo.getLog().isDebugEnabled()) { + args.add("-verbose"); + } + + if (classes != null) { + for (Iterator i = classes.iterator(); i.hasNext(); ) { + args.add((String)i.next()); + } + } + + return (String[])args.toArray(new String[args.size()]); + } +} + diff --git a/src/main/java/org/apache/maven/plugin/nar/Lib.java b/src/main/java/org/apache/maven/plugin/nar/Lib.java new file mode 100644 index 0000000..6f47527 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Lib.java @@ -0,0 +1,97 @@ +// Copyright FreeHEP, 2005. +package org.freehep.maven.nar; + +import java.io.File; +import java.util.Iterator; +import java.util.List; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.LinkerDef; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.tools.ant.Project; + +/** + * Keeps info on a library + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Lib.java eda4d0bbde3d 2007/07/03 16:52:10 duns $ + */ +public class Lib { + + /** + * Name of the library, or a dependency groupId:artifactId if this library contains sublibraries + * + * @parameter expression="" + * @required + */ + private String name; + + /** + * Type of linking for this library + * + * @parameter expression="" default-value="shared" + * @required + */ + private String type = Library.SHARED; + + /** + * Location for this library + * + * @parameter expression="" + * @required + */ + private File directory; + + /** + * Sub libraries for this library + * + * @parameter expression="" + */ + private List/*<Lib>*/ libs; + + public void addLibSet(AbstractDependencyMojo mojo, LinkerDef linker, Project antProject) throws MojoFailureException, MojoExecutionException { + addLibSet(mojo, linker, antProject, name, directory); + } + + private void addLibSet(AbstractDependencyMojo mojo, LinkerDef linker, Project antProject, String name, File dir) throws MojoFailureException, MojoExecutionException { + if (name == null) { + throw new MojoFailureException("NAR: Please specify <Name> as part of <Lib>"); + } + if (libs == null) { + if (!type.equals("framework") && (dir == null)) { + throw new MojoFailureException("NAR: Please specify <Directory> as part of <Lib>"); + } + LibrarySet libSet = new LibrarySet(); + libSet.setProject(antProject); + libSet.setLibs(new CUtil.StringArrayBuilder(name)); + LibraryTypeEnum libType = new LibraryTypeEnum(); + libType.setValue(type); + libSet.setType(libType); + libSet.setDir(dir); + linker.addLibset(libSet); + } else { + List dependencies = mojo.getNarManager().getNarDependencies("compile"); + for (Iterator i=libs.iterator(); i.hasNext(); ) { + Lib lib = (Lib)i.next(); + String[] ids = name.split(":",2); + if (ids.length != 2) { + throw new MojoFailureException("NAR: Please specify <Name> as part of <Lib> in format 'groupId:artifactId'"); + } + for (Iterator j=dependencies.iterator(); j.hasNext(); ) { + Artifact dependency = (Artifact)j.next(); + if (dependency.getGroupId().equals(ids[0]) && dependency.getArtifactId().equals(ids[1])) { + File narDir = new File(mojo.getNarManager().getNarFile(dependency).getParentFile(), "nar/lib/"+mojo.getAOL()+"/"+lib.type); + String narName = dependency.getArtifactId()+"-"+lib.name+"-"+dependency.getVersion(); + lib.addLibSet(mojo, linker, antProject, narName, narDir); + } + } + } + } + } +} + diff --git a/src/main/java/org/apache/maven/plugin/nar/Library.java b/src/main/java/org/apache/maven/plugin/nar/Library.java new file mode 100644 index 0000000..abda679 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Library.java @@ -0,0 +1,117 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Sets up a library to create + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Library.java 19804ec9b6b9 2007/09/04 23:36:51 duns $ + */ +public class Library implements Executable { + + public static final String STATIC = "static"; + public static final String SHARED = "shared"; + public static final String EXECUTABLE = "executable"; + public static final String JNI = "jni"; + public static final String PLUGIN = "plugin"; + public static final String NONE = "none"; // no library produced + + /** + * Type of the library to generate. Possible choices are: "plugin", + * "shared", "static", "jni" or "executable". Defaults to "shared". + * + * @parameter expression="" + */ + protected String type = "shared"; + + /** + * Link with stdcpp if necessary Defaults to true. + * + * @parameter expression="" + */ + protected boolean linkCPP = true; + + /** + * Link with fortran runtime if necessary Defaults to false. + * + * @parameter expression="" + */ + protected boolean linkFortran = false; + + /** + * If specified will create the NarSystem class with methods + * to load a JNI library. + * + * @parameter expression="" + */ + protected String narSystemPackage = null; + + /** + * Name of the NarSystem class + * + * @parameter expression="NarSystem" + * @required + */ + protected String narSystemName = "NarSystem"; + + /** + * The target directory into which to generate the output. + * + * @parameter expression="${project.build.dir}/nar/nar-generated" + * @required + */ + protected File narSystemDirectory = new File("target/nar/nar-generated"); + + /** + * When true and if type is "executable" run this executable. + * Defaults to false; + * + * @parameter expression="" + */ + protected boolean run=false; + + /** + * Arguments to be used for running this executable. + * Defaults to empty list. This option is + * only used if run=true and type=executable. + * + * @parameter expression="" + */ + protected List/*<String>*/ args = new ArrayList(); + + public String getType() { + return type; + } + + public boolean linkCPP() { + return linkCPP; + } + + public boolean linkFortran() { + return linkFortran; + } + + public String getNarSystemPackage() { + return narSystemPackage; + } + + public boolean shouldRun() { + return run; + } + + public List/*<String>*/ getArgs() { + return args; + } + + public String getNarSystemName() { + return narSystemName; + } + + public File getNarSystemDirectory() { + return narSystemDirectory; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Linker.java b/src/main/java/org/apache/maven/plugin/nar/Linker.java new file mode 100644 index 0000000..e148b31 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Linker.java @@ -0,0 +1,348 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.LinkedList; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.LinkerDef; +import net.sf.antcontrib.cpptasks.LinkerEnum; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +import net.sf.antcontrib.cpptasks.types.LinkerArgument; +import net.sf.antcontrib.cpptasks.types.SystemLibrarySet; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.tools.ant.Project; +import org.codehaus.plexus.util.FileUtils; + +/** + * Linker tag + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Linker.java 22df3eb318cc 2007/09/06 18:55:15 duns $ + */ +public class Linker { + + /** + * The Linker Some choices are: "msvc", "g++", "CC", "icpc", ... Default is + * Architecture-OS-Linker specific: FIXME: table missing + * + * @parameter expression="" + */ + private String name; + + /** + * Enables or disables incremental linking. + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean incremental = false; + + /** + * Enables or disables the production of a map file. + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean map = false; + + /** + * Options for the linker Defaults to Architecture-OS-Linker specific + * values. FIXME table missing + * + * @parameter expression="" + */ + private List options; + + /** + * Options for the linker as a whitespace separated list. + * Defaults to Architecture-OS-Linker specific values. + * Will work in combination with <options>. + * + * @parameter expression="" + */ + private String optionSet; + + /** + * Clears default options + * + * @parameter expression="" default-value="false" + * @required + */ + private boolean clearDefaultOptions; + + /** + * Adds libraries to the linker. + * + * @parameter expression="" + */ + private List/* <Lib> */libs; + + /** + * Adds libraries to the linker. Will work in combination with <libs>. + * The format is comma separated, colon-delimited values (name:type:dir), + * like "myLib:shared:/home/me/libs/, otherLib:static:/some/path". + * + * @parameter expression="" + */ + private String libSet; + + /** + * Adds system libraries to the linker. + * + * @parameter expression="" + */ + private List/* <SysLib> */sysLibs; + + /** + * Adds system libraries to the linker. Will work in combination with <sysLibs>. + * The format is comma separated, colon-delimited values (name:type), + * like "dl:shared, pthread:shared". + * + * @parameter expression="" + */ + private String sysLibSet; + + /** + * <p> + * Specifies the link ordering of libraries that come from nar dependencies. The format is + * a comma separated list of dependency names, given as groupId:artifactId. + * </p> + * + * <p> + * Example: <narDependencyLibOrder>someGroup:myProduct, other.group:productB<narDependencyLibOrder> + * </p> + * + * @parameter expression="" + */ + private String narDependencyLibOrder; + + + public Linker() { + // default constructor for use as TAG + } + + /** + * For use with specific named linker. + * + * @param name + */ + public Linker(String name) { + this.name = name; + } + + public String getName(Properties defaults, String prefix) + throws MojoFailureException { + if ((name == null) && (defaults != null) && (prefix != null)) { + name = defaults.getProperty(prefix + "linker"); + } + if (name == null) { + throw new MojoFailureException( + "NAR: Please specify a <Name> as part of <Linker>"); + } + return name; + } + + public LinkerDef getLinker(AbstractCompileMojo mojo, Project antProject, + String os, String prefix, String type) throws MojoFailureException, + MojoExecutionException { + if (name == null) { + throw new MojoFailureException( + "NAR: Please specify a <Name> as part of <Linker>"); + } + + LinkerDef linker = new LinkerDef(); + linker.setProject(antProject); + LinkerEnum linkerEnum = new LinkerEnum(); + linkerEnum.setValue(name); + linker.setName(linkerEnum); + + // incremental, map + linker.setIncremental(incremental); + linker.setMap(map); + + // Add definitions (Window only) + if (os.equals(OS.WINDOWS) + && (type.equals(Library.SHARED) || type.equals(Library.JNI))) { + Set defs = new HashSet(); + try { + File cSrcDir = mojo.getC().getSourceDirectory(); + if (cSrcDir.exists()) + defs.addAll(FileUtils.getFiles(cSrcDir, "**/*.def", null)); + } catch (IOException e) { + } + try { + File cppSrcDir = mojo.getCpp().getSourceDirectory(); + if (cppSrcDir.exists()) + defs + .addAll(FileUtils.getFiles(cppSrcDir, "**/*.def", + null)); + } catch (IOException e) { + } + try { + File fortranSrcDir = mojo.getFortran().getSourceDirectory(); + if (fortranSrcDir.exists()) + defs.addAll(FileUtils.getFiles(fortranSrcDir, "**/*.def", + null)); + } catch (IOException e) { + } + + for (Iterator i = defs.iterator(); i.hasNext();) { + LinkerArgument arg = new LinkerArgument(); + arg.setValue("/def:" + (File) i.next()); + linker.addConfiguredLinkerArg(arg); + } + } + + // Add options to linker + if (options != null) { + for (Iterator i = options.iterator(); i.hasNext();) { + LinkerArgument arg = new LinkerArgument(); + arg.setValue((String) i.next()); + linker.addConfiguredLinkerArg(arg); + } + } + + if (optionSet != null) { + + String[] opts = optionSet.split("\\s"); + + for (int i = 0; i < opts.length; i++) { + + LinkerArgument arg = new LinkerArgument(); + + arg.setValue(opts[i]); + linker.addConfiguredLinkerArg(arg); + } + } + + if (!clearDefaultOptions) { + String options = NarUtil.getDefaults().getProperty( + prefix + "options"); + if (options != null) { + String[] option = options.split(" "); + for (int i = 0; i < option.length; i++) { + LinkerArgument arg = new LinkerArgument(); + arg.setValue(option[i]); + linker.addConfiguredLinkerArg(arg); + } + } + } + + // record the preference for nar dependency library link order + if (narDependencyLibOrder != null) { + + List libOrder = new LinkedList(); + + String[] libs = narDependencyLibOrder.split(","); + + for (int i = 0; i < libs.length; i++) { + libOrder.add(libs[i].trim()); + } + + mojo.setDependencyLibOrder(libOrder); + } + + // Add Libraries to linker + if ((libs != null) || (libSet != null)) { + + if (libs != null) { + + for (Iterator i = libs.iterator(); i.hasNext();) { + + Lib lib = (Lib) i.next(); + lib.addLibSet(mojo, linker, antProject); + } + } + + if (libSet != null) { + addLibraries(libSet, linker, antProject, false); + } + } + else { + + String libsList = NarUtil.getDefaults() + .getProperty(prefix + "libs"); + + addLibraries(libsList, linker, antProject, false); + } + + // Add System Libraries to linker + if ((sysLibs != null) || (sysLibSet != null)) { + + if (sysLibs != null) { + + for (Iterator i = sysLibs.iterator(); i.hasNext();) { + + SysLib sysLib = (SysLib) i.next(); + linker.addSyslibset(sysLib.getSysLibSet(antProject)); + } + } + + if (sysLibSet != null) { + addLibraries(sysLibSet, linker, antProject, true); + } + } + else { + + String sysLibsList = NarUtil.getDefaults().getProperty( + prefix + "sysLibs"); + + addLibraries(sysLibsList, linker, antProject, true); + } + + return linker; + } + + + private void addLibraries(String libraryList, LinkerDef linker, Project antProject, boolean isSystem) { + + if (libraryList == null) { + return; + } + + String[] lib = libraryList.split(","); + + for (int i = 0; i < lib.length; i++) { + + String[] libInfo = lib[i].trim().split(":", 3); + + LibrarySet librarySet = new LibrarySet(); + + if (isSystem) { + librarySet = new SystemLibrarySet(); + } + + librarySet.setProject(antProject); + librarySet.setLibs(new CUtil.StringArrayBuilder(libInfo[0])); + + if (libInfo.length > 1) { + + LibraryTypeEnum libType = new LibraryTypeEnum(); + + libType.setValue(libInfo[1]); + librarySet.setType(libType); + + if (!isSystem && (libInfo.length > 2)) { + librarySet.setDir(new File(libInfo[2])); + } + } + + if (!isSystem) { + linker.addLibset(librarySet); + } + else { + linker.addSyslibset((SystemLibrarySet)librarySet); + } + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarArchiver.java b/src/main/java/org/apache/maven/plugin/nar/NarArchiver.java new file mode 100644 index 0000000..a70a21c --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarArchiver.java @@ -0,0 +1,12 @@ +// Copyright FreeHEP, 2005. +package org.freehep.maven.nar; + +import org.codehaus.plexus.archiver.zip.AbstractZipArchiver; + +/** + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarArchiver.java eda4d0bbde3d 2007/07/03 16:52:10 duns $ + */ +public class NarArchiver extends AbstractZipArchiver { +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarArtifact.java b/src/main/java/org/apache/maven/plugin/nar/NarArtifact.java new file mode 100644 index 0000000..76850b5 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarArtifact.java @@ -0,0 +1,26 @@ +// Copyright 2006, FreeHEP. +package org.freehep.maven.nar; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; + +/** + * + * @author duns + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarArtifact.java eda4d0bbde3d 2007/07/03 16:52:10 duns $ + */ +public class NarArtifact extends DefaultArtifact { + + private NarInfo narInfo; + + public NarArtifact(Artifact dependency, NarInfo narInfo) { + super(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersionRange(), + dependency.getScope(), dependency.getType(), dependency.getClassifier(), + dependency.getArtifactHandler(), dependency.isOptional()); + this.narInfo = narInfo; + } + + public NarInfo getNarInfo() { + return narInfo; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarArtifactHandler.java b/src/main/java/org/apache/maven/plugin/nar/NarArtifactHandler.java new file mode 100644 index 0000000..60b55d2 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarArtifactHandler.java @@ -0,0 +1,39 @@ +// Copyright FreeHEP, 2007. +package org.freehep.maven.nar; + +import org.apache.maven.artifact.handler.ArtifactHandler; + +/** + * + * @author Mark Donszelmann + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarArtifactHandler.java 76e8ff7ad2b0 2007/07/24 04:15:54 duns $ + */ +public class NarArtifactHandler implements ArtifactHandler { + public String getPackaging() { + return "nar"; + } + + public String getClassifier() { + return null; + } + + public String getDirectory() { + return getExtension() + "s"; + } + + public String getExtension() { + return "jar"; + } + + public String getLanguage() { + return "java"; + } + + public boolean isAddedToClasspath() { + return true; + } + + public boolean isIncludesDependencies() { + return false; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarAssemblyMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarAssemblyMojo.java new file mode 100644 index 0000000..658d688 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarAssemblyMojo.java @@ -0,0 +1,99 @@ +// Copyright FreeHEP, 2006-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.codehaus.plexus.util.FileUtils; + +/** + * Assemble libraries of NAR files. + * + * @goal nar-assembly + * @phase process-resources + * @requiresProject + * @requiresDependencyResolution + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarAssemblyMojo.java c867ab546be1 2007/07/05 21:26:30 duns $ + */ +public class NarAssemblyMojo extends AbstractDependencyMojo { + + /** + * List of classifiers which you want to assemble. Example ppc-MacOSX-g++-static, + * x86-Windows-msvc-shared, i386-Linux-g++-executable, .... + * + * @parameter expression="" + * @required + */ + private List classifiers; + + /** + * Copies the unpacked nar libraries and files into the projects target area + */ + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) { + getLog() + .info( + "***********************************************************************"); + getLog() + .info( + "NAR Assembly SKIPPED since no NAR libraries were built/downloaded."); + getLog() + .info( + "***********************************************************************"); + // NOTE: continue since the standard assemble mojo fails if we do + // not create the directories... + } + + for (Iterator j = classifiers.iterator(); j.hasNext();) { + String classifier = (String) j.next(); + + List narArtifacts = getNarManager().getNarDependencies("compile"); + List dependencies = getNarManager().getAttachedNarDependencies( + narArtifacts, classifier); + // this may make some extra copies... + for (Iterator d = dependencies.iterator(); d.hasNext();) { + Artifact dependency = (Artifact) d.next(); + getLog().debug("Assemble from " + dependency); + + // FIXME reported to maven developer list, isSnapshot + // changes behaviour + // of getBaseVersion, called in pathOf. + if (dependency.isSnapshot()) + ; + + File srcDir = new File(getLocalRepository().pathOf(dependency)); + srcDir = new File(getLocalRepository().getBasedir(), srcDir + .getParent()); + srcDir = new File(srcDir, "nar/"); + File dstDir = new File("target/nar/"); + try { + FileUtils.mkdir(dstDir.getPath()); + if (shouldSkip()) { + File note = new File(dstDir, "NAR_ASSEMBLY_SKIPPED"); + FileUtils + .fileWrite( + note.getPath(), + "The NAR Libraries of this distribution are missing because \n" + + "the NAR dependencies were not built/downloaded, presumably because\n" + + "the the distribution was built with the '-Dnar.skip=true' flag."); + } else { + getLog().debug("SrcDir: " + srcDir); + if (srcDir.exists()) { + FileUtils.copyDirectoryStructure(srcDir, dstDir); + } + } + } catch (IOException ioe) { + throw new MojoExecutionException( + "Failed to copy directory for dependency " + + dependency + " from "+srcDir+" to " + dstDir, ioe); + } + } + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarCompileMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarCompileMojo.java new file mode 100644 index 0000000..10db16e --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarCompileMojo.java @@ -0,0 +1,296 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.LinkerDef; +import net.sf.antcontrib.cpptasks.OutputTypeEnum; +import net.sf.antcontrib.cpptasks.RuntimeType; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LinkerArgument; +import net.sf.antcontrib.cpptasks.types.SystemLibrarySet; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.StringUtils; + +/** + * Compiles native source files. + * + * @goal nar-compile + * @phase compile + * @requiresDependencyResolution compile + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarCompileMojo.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public class NarCompileMojo extends AbstractCompileMojo { + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) + return; + + // make sure destination is there + getTargetDirectory().mkdirs(); + + // check for source files + int noOfSources = 0; + noOfSources += getSourcesFor(getCpp()).size(); + noOfSources += getSourcesFor(getC()).size(); + noOfSources += getSourcesFor(getFortran()).size(); + if (noOfSources > 0) { + for (Iterator i = getLibraries().iterator(); i.hasNext();) { + createLibrary(getAntProject(), (Library) i.next()); + } + } + + try { + // FIXME, should the include paths be defined at a higher level ? + getCpp().copyIncludeFiles(getMavenProject(), + new File(getTargetDirectory(), "include")); + } catch (IOException e) { + throw new MojoExecutionException( + "NAR: could not copy include files", e); + } + } + + private List getSourcesFor(Compiler compiler) throws MojoFailureException { + try { + File srcDir = compiler.getSourceDirectory(); + return srcDir.exists() ? FileUtils.getFiles(srcDir, StringUtils + .join(compiler.getIncludes().iterator(), ","), null) + : Collections.EMPTY_LIST; + } catch (IOException e) { + return Collections.EMPTY_LIST; + } + } + + private void createLibrary(Project antProject, Library library) + throws MojoExecutionException, MojoFailureException { + // configure task + CCTask task = new CCTask(); + task.setProject(antProject); + + // set max cores + task.setMaxCores(getMaxCores(getAOL())); + + // outtype + OutputTypeEnum outTypeEnum = new OutputTypeEnum(); + String type = library.getType(); + outTypeEnum.setValue(type); + task.setOuttype(outTypeEnum); + + // stdc++ + task.setLinkCPP(library.linkCPP()); + + // fortran + task.setLinkFortran(library.linkFortran()); + + // outDir + File outDir = new File(getTargetDirectory(), type + .equals(Library.EXECUTABLE) ? "bin" : "lib"); + outDir = new File(outDir, getAOL().toString()); + if (!type.equals(Library.EXECUTABLE)) + outDir = new File(outDir, type); + outDir.mkdirs(); + + // outFile + File outFile; + if (type.equals(Library.EXECUTABLE)) { + // executable has no version number + outFile = new File(outDir, getMavenProject().getArtifactId()); + } else { + outFile = new File(outDir, getOutput(getAOL())); + } + getLog().debug("NAR - output: '" + outFile + "'"); + task.setOutfile(outFile); + + // object directory + File objDir = new File(getTargetDirectory(), "obj"); + objDir = new File(objDir, getAOL().toString()); + objDir.mkdirs(); + task.setObjdir(objDir); + + // failOnError, libtool + task.setFailonerror(failOnError(getAOL())); + task.setLibtool(useLibtool(getAOL())); + + // runtime + RuntimeType runtimeType = new RuntimeType(); + runtimeType.setValue(getRuntime(getAOL())); + task.setRuntime(runtimeType); + + // add C++ compiler + task.addConfiguredCompiler(getCpp().getCompiler(type, getOutput(getAOL()))); + + // add C compiler + task.addConfiguredCompiler(getC().getCompiler(type, getOutput(getAOL()))); + + // add Fortran compiler + task.addConfiguredCompiler(getFortran().getCompiler(type, getOutput(getAOL()))); + + // add javah include path + File jniDirectory = getJavah().getJniDirectory(); + if (jniDirectory.exists()) + task.createIncludePath().setPath(jniDirectory.getPath()); + + // add java include paths + getJava().addIncludePaths(task, type); + + // add dependency include paths + for (Iterator i = getNarManager().getNarDependencies("compile") + .iterator(); i.hasNext();) { + // FIXME, handle multiple includes from one NAR + NarArtifact narDependency = (NarArtifact) i.next(); + String binding = narDependency.getNarInfo().getBinding(getAOL(), + Library.STATIC); + getLog().debug( + "Looking for " + narDependency + " found binding " + + binding); + if (!binding.equals(Library.JNI)) { + File include = new File(getNarManager().getNarFile( + narDependency).getParentFile(), "nar/include"); + getLog().debug("Looking for for directory: " + include); + if (include.exists()) { + task.createIncludePath().setPath(include.getPath()); + } + } + } + + // add linker + LinkerDef linkerDefinition = getLinker().getLinker(this, antProject, + getOS(), getAOL().getKey() + ".linker.", type); + task.addConfiguredLinker(linkerDefinition); + + // add dependency libraries + // FIXME: what about PLUGIN and STATIC, depending on STATIC, should we + // not add all libraries, see NARPLUGIN-96 + if (type.equals(Library.SHARED) || type.equals(Library.JNI) || type.equals(Library.EXECUTABLE)) { + + List depLibOrder = getDependencyLibOrder(); + List depLibs = getNarManager().getNarDependencies("compile"); + + // reorder the libraries that come from the nar dependencies + // to comply with the order specified by the user + if ((depLibOrder != null) && !depLibOrder.isEmpty()) { + + List tmp = new LinkedList(); + + for (Iterator i = depLibOrder.iterator(); i.hasNext();) { + + String depToOrderName = (String)i.next(); + + for (Iterator j = depLibs.iterator(); j.hasNext();) { + + NarArtifact dep = (NarArtifact)j.next(); + String depName = dep.getGroupId() + ":" + dep.getArtifactId(); + + if (depName.equals(depToOrderName)) { + + tmp.add(dep); + j.remove(); + } + } + } + + tmp.addAll(depLibs); + depLibs = tmp; + } + + for (Iterator i = depLibs.iterator(); i.hasNext();) { + + NarArtifact dependency = (NarArtifact) i.next(); + + // FIXME no handling of "local" + + // FIXME, no way to override this at this stage + String binding = dependency.getNarInfo().getBinding(getAOL(), + Library.STATIC); + getLog().debug("Using Binding: " + binding); + AOL aol = getAOL(); + aol = dependency.getNarInfo().getAOL(getAOL()); + getLog().debug("Using Library AOL: " + aol.toString()); + + if (!binding.equals(Library.JNI)) { + File dir = new File(getNarManager().getNarFile(dependency) + .getParentFile(), "nar/lib/" + aol.toString() + "/" + binding); + getLog().debug("Looking for Library Directory: " + dir); + if (dir.exists()) { + LibrarySet libSet = new LibrarySet(); + libSet.setProject(antProject); + + // FIXME, no way to override + String libs = dependency.getNarInfo().getLibs(getAOL()); + if ((libs != null) && !libs.equals("")) { + getLog().debug("Using LIBS = " + libs); + libSet.setLibs(new CUtil.StringArrayBuilder(libs)); + libSet.setDir(dir); + task.addLibset(libSet); + } + } else { + getLog() + .debug( + "Library Directory " + dir + + " does NOT exist."); + } + + // FIXME, look again at this, for multiple dependencies we may need to remove duplicates + String options = dependency.getNarInfo().getOptions(getAOL()); + if ((options != null) && !options.equals("")) { + getLog().debug("Using OPTIONS = " + options); + LinkerArgument arg = new LinkerArgument(); + arg.setValue(options); + linkerDefinition.addConfiguredLinkerArg(arg); + } + + String sysLibs = dependency.getNarInfo().getSysLibs( + getAOL()); + if ((sysLibs != null) && !sysLibs.equals("")) { + getLog().debug("Using SYSLIBS = " + sysLibs); + SystemLibrarySet sysLibSet = new SystemLibrarySet(); + sysLibSet.setProject(antProject); + + sysLibSet + .setLibs(new CUtil.StringArrayBuilder(sysLibs)); + task.addSyslibset(sysLibSet); + } + } + } + } + + // Add JVM to linker + getJava().addRuntime(task, getJavaHome(getAOL()), getOS(), + getAOL().getKey() + "java."); + + // execute + try { + task.execute(); + } catch (BuildException e) { + throw new MojoExecutionException("NAR: Compile failed", e); + } + + // FIXME, this should be done in CPPTasks at some point + if (getRuntime(getAOL()).equals("dynamic") && + getOS().equals(OS.WINDOWS) && + getLinker().getName(null, null).equals("msvc") && + NarUtil.getEnv("MSVCVer", "MSVCVer", "6.0").startsWith("8.")) { + String libType = library.getType(); + if (libType.equals(Library.JNI) || libType.equals(Library.SHARED)) { + String dll = outFile.getPath()+".dll"; + String manifest = dll+".manifest"; + int result = NarUtil.runCommand("mt.exe", new String[] {"/manifest", manifest, "/outputresource:"+dll+";#2"}, null, getLog()); + if (result != 0) + throw new MojoFailureException("MT.EXE failed with exit code: " + result); + } + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarConstants.java b/src/main/java/org/apache/maven/plugin/nar/NarConstants.java new file mode 100644 index 0000000..2d80cd6 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarConstants.java @@ -0,0 +1,14 @@ +package org.freehep.maven.nar; + +public interface NarConstants { + public final static String NAR_EXTENSION = "nar"; + public final static String NAR_NO_ARCH = "noarch"; + public final static String NAR_ROLE_HINT = "nar-library"; + public final static String NAR_TYPE = "nar"; + + public final static int LOG_LEVEL_ERROR = 0; + public final static int LOG_LEVEL_WARNING = 1; + public final static int LOG_LEVEL_INFO = 2; + public final static int LOG_LEVEL_VERBOSE = 3; + public final static int LOG_LEVEL_DEBUG = 4; +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarDownloadMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarDownloadMojo.java new file mode 100644 index 0000000..f4830a8 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarDownloadMojo.java @@ -0,0 +1,72 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.artifact.resolver.ArtifactResolver; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + * Downloads any dependent NAR files. This includes the noarch and aol type NAR files. + * + * @goal nar-download + * @phase generate-sources + * @requiresProject + * @requiresDependencyResolution + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarDownloadMojo.java c867ab546be1 2007/07/05 21:26:30 duns $ + */ +public class NarDownloadMojo extends AbstractDependencyMojo { + + /** + * Artifact resolver, needed to download source jars for inclusion in + * classpath. + * + * @component role="org.apache.maven.artifact.resolver.ArtifactResolver" + * @required + * @readonly + */ + private ArtifactResolver artifactResolver; + + /** + * Remote repositories which will be searched for source attachments. + * + * @parameter expression="${project.remoteArtifactRepositories}" + * @required + * @readonly + */ + private List remoteArtifactRepositories; + + /** + * List of classifiers which you want download. Example ppc-MacOSX-g++, + * x86-Windows-msvc, i386-Linux-g++. + * + * @parameter expression="" + */ + private List classifiers; + + public void execute() throws MojoExecutionException, MojoFailureException { + getLog().info("Using AOL: "+getAOL()); + + if (shouldSkip()) { + getLog().info("***********************************************************************"); + getLog().info("NAR Plugin SKIPPED, no NAR Libraries will be produced."); + getLog().info("***********************************************************************"); + + return; + } + + List narArtifacts = getNarManager().getNarDependencies("compile"); + if (classifiers == null) { + getNarManager().downloadAttachedNars(narArtifacts, remoteArtifactRepositories, + artifactResolver, null); + } else { + for (Iterator j = classifiers.iterator(); j.hasNext();) { + getNarManager().downloadAttachedNars(narArtifacts, remoteArtifactRepositories, + artifactResolver, (String) j.next()); + } + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarInfo.java b/src/main/java/org/apache/maven/plugin/nar/NarInfo.java new file mode 100644 index 0000000..b34d9b2 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarInfo.java @@ -0,0 +1,169 @@ +// Copyright FreeHEP, 2006-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.Properties; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.apache.maven.plugin.logging.Log; + +/** + * + * @author Mark Donszelmann + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarInfo.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public class NarInfo { + + public static final String NAR_PROPERTIES = "nar.properties"; + private String groupId, artifactId, version; + private Properties info; + private Log log; + + public NarInfo(String groupId, String artifactId, String version, Log log) { + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + this.log = log; + info = new Properties(); + + // Fill with general properties.nar file + File propertiesDir = new File("src/main/resources/META-INF/nar/" + + groupId + "/" + artifactId); + if (!propertiesDir.exists()) { + propertiesDir.mkdirs(); + } + File propertiesFile = new File(propertiesDir, NarInfo.NAR_PROPERTIES); + try { + info.load(new FileInputStream(propertiesFile)); + } catch (IOException ioe) { + // ignored + } + + } + + public String toString() { + StringBuffer s = new StringBuffer("NarInfo for "); + s.append(groupId); + s.append(":"); + s.append(artifactId); + s.append("-"); + s.append(version); + s.append(" {\n"); + + for (Iterator i = info.keySet().iterator(); i.hasNext();) { + String key = (String) i.next(); + s.append(" "); + s.append(key); + s.append("='"); + s.append(info.getProperty(key, "<null>")); + s.append("'\n"); + } + + s.append("}\n"); + return s.toString(); + } + + public boolean exists(JarFile jar) { + return getNarPropertiesEntry(jar) != null; + } + + public void read(JarFile jar) throws IOException { + info.load(jar.getInputStream(getNarPropertiesEntry(jar))); + } + + private JarEntry getNarPropertiesEntry(JarFile jar) { + return jar.getJarEntry("META-INF/nar/" + groupId + "/" + artifactId + + "/" + NAR_PROPERTIES); + } + + /** + * No binding means default binding. + * + * @param aol + * @return + */ + public String getBinding(AOL aol, String defaultBinding) { + return getProperty(aol, "libs.binding", defaultBinding); + } + + public void setBinding(AOL aol, String value) { + setProperty(aol, "libs.binding", value); + } + + // FIXME replace with list of AttachedNarArtifacts + public String[] getAttachedNars(AOL aol, String type) { + String attachedNars = getProperty(aol, "nar." + type); + return attachedNars != null ? attachedNars.split(",") : null; + } + + public void addNar(AOL aol, String type, String nar) { + String nars = getProperty(aol, "nar." + type); + nars = (nars == null) ? nar : nars + ", " + nar; + setProperty(aol, "nar." + type, nars); + } + + public void setNar(AOL aol, String type, String nar) { + setProperty(aol, "nar." + type, nar); + } + + public AOL getAOL(AOL aol) { + return aol == null ? null : new AOL(getProperty(aol, aol.toString(), aol.toString())); + } + + public String getOptions(AOL aol) { + return getProperty(aol, "linker.options"); + } + + public String getLibs(AOL aol) { + return getProperty(aol, "libs.names", artifactId + "-" + version); + } + + public String getSysLibs(AOL aol) { + return getProperty(aol, "syslibs.names"); + } + + public void writeToFile(File file) throws IOException { + info.store(new FileOutputStream((file)), "NAR Properties for " + + groupId + "." + artifactId + "-" + version); + } + + private void setProperty(AOL aol, String key, String value) { + if (aol == null) { + info.setProperty(key, value); + } else { + info.setProperty(aol.toString() + "." + key, value); + } + } + + public String getProperty(AOL aol, String key) { + return getProperty(aol, key, (String)null); + } + + public String getProperty(AOL aol, String key, String defaultValue) { + if (key == null) + return defaultValue; + String value = info.getProperty(key, defaultValue); + value = aol == null ? value : info.getProperty(aol.toString() + "." + + key, value); + log.debug("getProperty(" + aol + ", " + key + ", " + + defaultValue + ") = " + value); + return value; + } + + public int getProperty(AOL aol, String key, int defaultValue) { + return Integer.parseInt(getProperty(aol, key, Integer.toString(defaultValue))); + } + + public boolean getProperty(AOL aol, String key, boolean defaultValue) { + return Boolean.parseBoolean(getProperty(aol, key, String.valueOf(defaultValue))); + } + + public File getProperty(AOL aol, String key, File defaultValue) { + return new File(getProperty(aol, key, defaultValue.getPath())); + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarIntegrationTestMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarIntegrationTestMojo.java new file mode 100644 index 0000000..19884c2 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarIntegrationTestMojo.java @@ -0,0 +1,987 @@ +// Copied from Maven maven-surefire-plugin 2.3, 2006-2007 +package org.freehep.maven.nar; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.resolver.ArtifactNotFoundException; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.artifact.resolver.ArtifactResolver; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; +import org.apache.maven.surefire.booter.ForkConfiguration; +import org.apache.maven.surefire.booter.SurefireBooter; +import org.apache.maven.surefire.booter.SurefireBooterForkException; +import org.apache.maven.surefire.booter.SurefireExecutionException; +import org.apache.maven.surefire.report.BriefConsoleReporter; +import org.apache.maven.surefire.report.BriefFileReporter; +import org.apache.maven.surefire.report.ConsoleReporter; +import org.apache.maven.surefire.report.DetailedConsoleReporter; +import org.apache.maven.surefire.report.FileReporter; +import org.apache.maven.surefire.report.ForkingConsoleReporter; +import org.apache.maven.surefire.report.XMLReporter; +import org.codehaus.plexus.util.StringUtils; + +/** + * Run integration tests using Surefire. + * + * This goal was copied from Maven's surefire plugin to accomodate a few things + * for the NAR plugin: 1. To test a jar file with its native module we can only + * run after the package phase, so we use the integration-test phase. 2. We need + * to set java.library.path to an AOL (architecture-os-linker) specific value, + * but AOL is only known in the NAR plugin and thus cannot be set from the pom. + * 3. To have the java.library.path definition picked up by java we need the + * "pertest" forkmode. + * + * 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. + * + * @author Jason van Zyl (modified by Mark Donszelmann, noted by FREEHEP) + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarIntegrationTestMojo.java eeac31f37379 2007/07/24 04:02:00 duns $, + * 2.3 maven repository maven-surefire-plugin + * @requiresDependencyResolution test + * @goal nar-integration-test + * @phase integration-test + */ +// FREEHEP, changed class name, inheritence, goal and phase +public class NarIntegrationTestMojo extends AbstractCompileMojo { + // FREEHEP added test for JNI module + private boolean testJNIModule() { + for (Iterator i = getLibraries().iterator(); i.hasNext();) { + Library lib = (Library) i.next(); + if (lib.getType().equals(Library.JNI)) + return true; + } + return false; + } + + // FREEHEP added to get names + /** + * @parameter expression="${project}" + * @readonly + * @required + */ + private MavenProject project; + + // FREEHEP added because of naming conflict + /** + * Skip running of NAR plugins (any) altogether. + * + * @parameter expression="${nar.skip}" default-value="false" + */ + private boolean skipNAR; + + /** + * Set this to 'true' to bypass unit tests entirely. Its use is NOT + * RECOMMENDED, but quite convenient on occasion. + * + * @parameter expression="${maven.test.skip}" + */ + private boolean skip; + + /** + * Set this to 'true' to bypass unit tests execution, but still compile + * them. Its use is NOT RECOMMENDED, but quite convenient on occasion. + * + * @parameter expression="${maven.test.skip.exec}" + */ + private boolean skipExec; + + /** + * Set this to true to ignore a failure during testing. Its use is NOT + * RECOMMENDED, but quite convenient on occasion. + * + * @parameter expression="${maven.test.failure.ignore}" + */ + private boolean testFailureIgnore; + + /** + * The base directory of the project being tested. This can be obtained in + * your unit test by System.getProperty("basedir"). + * + * @parameter expression="${basedir}" + * @required + */ + private File basedir; + + // FIXME this field is not used + /** + * The directory containing generated classes of the project being tested. + * + * @parameter expression="${project.build.outputDirectory}" + * @required + */ + // FREEHEP + // private File classesDirectory; + /** + * The directory containing generated test classes of the project being + * tested. + * + * @parameter expression="${project.build.testOutputDirectory}" + * @required + */ + private File testClassesDirectory; + + /** + * The classpath elements of the project being tested. + * + * @parameter expression="${project.testClasspathElements}" + * @required + * @readonly + */ + private List classpathElements; + + /** + * Base directory where all reports are written to. + * + * @parameter expression="${project.build.directory}/surefire-reports" + */ + private File reportsDirectory; + + /** + * The test source directory containing test class sources. + * + * @parameter expression="${project.build.testSourceDirectory}" + * @required + */ + private File testSourceDirectory; + + /** + * Specify this parameter(can be a comma separated list) if you want to use + * the test pattern matching notation, Ant pattern matching, to select tests + * to run. The Ant pattern will be used to create an include pattern + * formatted like <code>**/${test}.java</code> When used, the + * <code>includes</code> and <code>excludes</code> patterns parameters + * are ignored. + * + * @parameter expression="${test}" + */ + private String test; + + /** + * List of patterns (separated by commas) used to specify the tests that + * should be included in testing. When not specified and when the + * <code>test</code> parameter is not specified, the default includes will + * be + * <code>**/Test*.java **/*Test.java **/*TestCase.java</code> + * + * @parameter + */ + private List includes; + + /** + * List of patterns (separated by commas) used to specify the tests that + * should be excluded in testing. When not specified and when the + * <code>test</code> parameter is not specified, the default excludes will + * be + * <code>**/Abstract*Test.java **/Abstract*TestCase.java **/*$*</code> + * + * @parameter + */ + private List excludes; + + /** + * ArtifactRepository of the localRepository. To obtain the directory of + * localRepository in unit tests use System.setProperty( "localRepository"). + * + * @parameter expression="${localRepository}" + * @required + * @readonly + */ + // FREEHEP removed, already in superclass + // private ArtifactRepository localRepository; + /** + * List of System properties to pass to the JUnit tests. + * + * @parameter + */ + private Properties systemProperties; + + /** + * Map of of plugin artifacts. + * + * @parameter expression="${plugin.artifactMap}" + * @required + * @readonly + */ + private Map pluginArtifactMap; + + /** + * Map of of project artifacts. + * + * @parameter expression="${project.artifactMap}" + * @required + * @readonly + */ + private Map projectArtifactMap; + + /** + * Option to print summary of test suites or just print the test cases that + * has errors. + * + * @parameter expression="${surefire.printSummary}" default-value="true" + */ + private boolean printSummary; + + /** + * Selects the formatting for the test report to be generated. Can be set as + * brief or plain. + * + * @parameter expression="${surefire.reportFormat}" default-value="brief" + */ + private String reportFormat; + + /** + * Option to generate a file test report or just output the test report to + * the console. + * + * @parameter expression="${surefire.useFile}" default-value="true" + */ + private boolean useFile; + + /** + * When forking, set this to true to redirect the unit test standard output + * to a file (found in reportsDirectory/testName-output.txt). + * + * @parameter expression="${maven.test.redirectTestOutputToFile}" + * default-value="false" + */ + private boolean redirectTestOutputToFile; + + /** + * Option to specify the forking mode. Can be "never", "once" or "always". + * "none" and "pertest" are also accepted for backwards compatibility. + * + * @parameter expression="${forkMode}" default-value="once" + */ + private String forkMode; + + /** + * Option to specify the jvm (or path to the java executable) to use with + * the forking options. For the default, the jvm will be the same as the one + * used to run Maven. + * + * @parameter expression="${jvm}" + */ + private String jvm; + + /** + * Arbitrary options to set on the command line. + * + * @parameter expression="${argLine}" + */ + private String argLine; + + /** + * Additional environments to set on the command line. + * + * @parameter + */ + private Map environmentVariables = new HashMap(); + + /** + * Command line working directory. + * + * @parameter + */ + private File workingDirectory; + + /** + * When false it makes tests run using the standard classloader delegation + * instead of the default Maven isolated classloader. Only used when forking + * (forkMode is not "none").<br/> Setting it to false helps with some + * problems caused by conflicts between xml parsers in the classpath and the + * Java 5 provider parser. + * + * @parameter expression="${childDelegation}" default-value="false" + */ + private boolean childDelegation; + + /** + * Groups for this test. Only classes/methods/etc decorated with one of the + * groups specified here will be included in test run, if specified. + * + * @parameter expression="${groups}" + */ + private String groups; + + /** + * Excluded groups. Any methods/classes/etc with one of the groups specified + * in this list will specifically not be run. + * + * @parameter expression="${excludedGroups}" + */ + private String excludedGroups; + + /** + * List of TestNG suite xml file locations, seperated by commas. It should + * be noted that if suiteXmlFiles is specified, <b>no</b> other tests will + * be run, ignoring other parameters, like includes and excludes. + * + * @parameter + */ + private File[] suiteXmlFiles; + + /** + * The attribute thread-count allows you to specify how many threads should + * be allocated for this execution. Only makes sense to use in conjunction + * with parallel. + * + * @parameter expression="${threadCount}" default-value="5" + */ + private int threadCount; + + /** + * When you use the parallel attribute, TestNG will try to run all your test + * methods in separate threads, except for methods that depend on each + * other, which will be run in the same thread in order to respect their + * order of execution. + * + * @parameter expression="${parallel}" default-value="false" + * @todo test how this works with forking, and console/file output + * parallelism + */ + private boolean parallel; + + /** + * Whether to trim the stack trace in the reports to just the lines within + * the test, or show the full trace. + * + * @parameter expression="${trimStackTrace}" default-value="true" + */ + private boolean trimStackTrace; + + /** + * Resolves the artifacts needed. + * + * @component + */ + private ArtifactResolver artifactResolver; + + /** + * Creates the artifact + * + * @component + */ + private ArtifactFactory artifactFactory; + + /** + * The plugin remote repositories declared in the pom. + * + * @parameter expression="${project.pluginArtifactRepositories}" + */ + private List remoteRepositories; + + /** + * For retrieval of artifact's metadata. + * + * @component + */ + private ArtifactMetadataSource metadataSource; + + private static final String BRIEF_REPORT_FORMAT = "brief"; + + private static final String PLAIN_REPORT_FORMAT = "plain"; + + private Properties originalSystemProperties; + + /** + * Flag to disable the generation of report files in xml format. + * + * @parameter expression="${disableXmlReport}" default-value="false" + */ + private boolean disableXmlReport; + + /** + * Option to pass dependencies to the system's classloader instead of using + * an isolated class loader when forking. Prevents problems with JDKs which + * implement the service provider lookup mechanism by using the system's + * classloader. + * + * @parameter expression="${surefire.useSystemClassLoader}" + * default-value="false" + */ + private boolean useSystemClassLoader; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (verifyParameters()) { + SurefireBooter surefireBooter = constructSurefireBooter(); + + getLog().info("Surefire report directory: " + reportsDirectory); + + boolean success; + try { + success = surefireBooter.run(); + } catch (SurefireBooterForkException e) { + throw new MojoExecutionException(e.getMessage(), e); + } catch (SurefireExecutionException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + + if (originalSystemProperties != null) { + // restore system properties + System.setProperties(originalSystemProperties); + } + + if (!success) { + String msg = "There are test failures."; + + if (testFailureIgnore) { + getLog().error(msg); + } else { + throw new MojoFailureException(msg); + } + } + } + } + + private boolean verifyParameters() throws MojoFailureException { + // FREEHEP, shouldSkip() does not work... + if (skipNAR) { + getLog() + .info( + "***********************************************************************"); + getLog() + .info( + "NAR Integration Tests are SKIPPED since no NAR libraries were built."); + getLog() + .info( + "***********************************************************************"); + return false; + } + + if (skip || skipExec) { + getLog().info("Tests are skipped."); + return false; + } else if (!testClassesDirectory.exists()) { + getLog().info("No tests to run."); + return false; + } + + if (parallel) { + if (threadCount < 1) { + throw new MojoFailureException( + "Must have at least one thread in parallel mode"); + } + } + + if (useSystemClassLoader + && ForkConfiguration.FORK_NEVER.equals(forkMode)) { + getLog() + .warn( + "useSystemClassloader=true setting has no effect when not forking"); + } + + return true; + } + + private SurefireBooter constructSurefireBooter() + throws MojoExecutionException, MojoFailureException { + SurefireBooter surefireBooter = new SurefireBooter(); + + Artifact surefireArtifact = (Artifact) pluginArtifactMap + .get("org.apache.maven.surefire:surefire-booter"); + if (surefireArtifact == null) { + throw new MojoExecutionException( + "Unable to locate surefire-booter in the list of plugin artifacts"); + } + + surefireArtifact.isSnapshot(); // TODO: this is ridiculous, but it + // fixes getBaseVersion to be -SNAPSHOT + // if needed + + Artifact junitArtifact; + Artifact testNgArtifact; + try { + addArtifact(surefireBooter, surefireArtifact); + + junitArtifact = (Artifact) projectArtifactMap.get("junit:junit"); + + // TODO: this is pretty manual, but I'd rather not require the + // plugin > dependencies section right now + testNgArtifact = (Artifact) projectArtifactMap + .get("org.testng:testng"); + + if (testNgArtifact != null) { + addArtifact(surefireBooter, testNgArtifact); + + VersionRange range = VersionRange + .createFromVersionSpec("[4.7,)"); + if (!range.containsVersion(testNgArtifact.getSelectedVersion())) { + throw new MojoFailureException( + "TestNG support requires version 4.7 or above. You have declared version " + + testNgArtifact.getVersion()); + } + + // The plugin uses a JDK based profile to select the right + // testng. We might be explicity using a + // different one since its based on the source level, not the + // JVM. Prune using the filter. + addProvider(surefireBooter, "surefire-testng", surefireArtifact + .getBaseVersion(), testNgArtifact); + } else if (junitArtifact != null + && junitArtifact.getBaseVersion().startsWith("4")) { + addProvider(surefireBooter, "surefire-junit4", surefireArtifact + .getBaseVersion(), null); + } else { + // add the JUnit provider as default - it doesn't require JUnit + // to be present, + // since it supports POJO tests. + addProvider(surefireBooter, "surefire-junit", surefireArtifact + .getBaseVersion(), null); + } + } catch (ArtifactNotFoundException e) { + throw new MojoExecutionException( + "Unable to locate required surefire provider dependency: " + + e.getMessage(), e); + } catch (InvalidVersionSpecificationException e) { + throw new MojoExecutionException( + "Error determining the TestNG version requested: " + + e.getMessage(), e); + } catch (ArtifactResolutionException e) { + throw new MojoExecutionException( + "Error to resolving surefire provider dependency: " + + e.getMessage(), e); + } + + if (suiteXmlFiles != null && suiteXmlFiles.length > 0) { + if (testNgArtifact == null) { + throw new MojoExecutionException( + "suiteXmlFiles is configured, but there is no TestNG dependency"); + } + for (int i = 0; i < suiteXmlFiles.length; i++) { + File file = suiteXmlFiles[i]; + if (file.exists()) { + surefireBooter + .addTestSuite( + "org.apache.maven.surefire.testng.TestNGXmlTestSuite", + new Object[] { + file, + testSourceDirectory + .getAbsolutePath() }); + } + } + } else { + List includes; + List excludes; + + if (test != null) { + // Check to see if we are running a single test. The raw + // parameter will + // come through if it has not been set. + + // FooTest -> **/FooTest.java + + includes = new ArrayList(); + + excludes = new ArrayList(); + + String[] testRegexes = StringUtils.split(test, ","); + + for (int i = 0; i < testRegexes.length; i++) { + includes.add("**/" + testRegexes[i] + ".java"); + } + } else { + includes = this.includes; + + excludes = this.excludes; + + // defaults here, qdox doesn't like the end javadoc value + // Have to wrap in an ArrayList as surefire expects an ArrayList + // instead of a List for some reason + if (includes == null || includes.size() == 0) { + includes = new ArrayList(Arrays.asList(new String[] { + "**/Test*.java", "**/*Test.java", + "**/*TestCase.java" })); + } + if (excludes == null || excludes.size() == 0) { + excludes = new ArrayList(Arrays.asList(new String[] { + "**/Abstract*Test.java", + "**/Abstract*TestCase.java", "**/*$*" })); + } + } + + if (testNgArtifact != null) { + surefireBooter + .addTestSuite( + "org.apache.maven.surefire.testng.TestNGDirectoryTestSuite", + new Object[] { testClassesDirectory, includes, + excludes, groups, excludedGroups, + Boolean.valueOf(parallel), + new Integer(threadCount), + testSourceDirectory.getAbsolutePath() }); + } else { + String junitDirectoryTestSuite; + // FREEHEP NP check + if (junitArtifact != null + && junitArtifact.getBaseVersion().startsWith("4")) { + junitDirectoryTestSuite = "org.apache.maven.surefire.junit4.JUnit4DirectoryTestSuite"; + } else { + junitDirectoryTestSuite = "org.apache.maven.surefire.junit.JUnitDirectoryTestSuite"; + } + + // fall back to JUnit, which also contains POJO support. Also it + // can run + // classes compiled against JUnit since it has a dependency on + // JUnit itself. + surefireBooter + .addTestSuite(junitDirectoryTestSuite, new Object[] { + testClassesDirectory, includes, excludes }); + } + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + getLog().debug("Test Classpath :"); + + // no need to add classes/test classes directory here - they are in the + // classpath elements already + + for (Iterator i = classpathElements.iterator(); i.hasNext();) { + String classpathElement = (String) i.next(); + + getLog().debug(" " + classpathElement); + + surefireBooter.addClassPathUrl(classpathElement); + } + + // ---------------------------------------------------------------------- + // Forking + // ---------------------------------------------------------------------- + + ForkConfiguration fork = new ForkConfiguration(); + + // FREEHEP + if (project.getPackaging().equals("nar") + || (getNarManager().getNarDependencies("test").size() > 0)) + forkMode = "pertest"; + + fork.setForkMode(forkMode); + + processSystemProperties(!fork.isForking()); + + if (getLog().isDebugEnabled()) { + showMap(systemProperties, "system property"); + } + + if (fork.isForking()) { + fork.setSystemProperties(systemProperties); + + if (jvm == null || "".equals(jvm)) { + // use the same JVM as the one used to run Maven (the + // "java.home" one) + jvm = System.getProperty("java.home") + File.separator + "bin" + + File.separator + "java"; + getLog().debug("Using JVM: " + jvm); + } + + fork.setJvmExecutable(jvm); + + if (workingDirectory != null) { + fork.setWorkingDirectory(workingDirectory); + } else { + fork.setWorkingDirectory(basedir); + } + + // BEGINFREEHEP + if (argLine == null) + argLine = ""; + + StringBuffer javaLibraryPath = new StringBuffer(); + if (testJNIModule()) { + // Add libraries to java.library.path for testing + File jniLibraryPathEntry = new File(project.getBasedir(), + "target/nar/lib/" + getAOL() + "/jni"); + if (jniLibraryPathEntry.exists()) { + getLog().debug( + "Adding library directory to java.library.path: " + + jniLibraryPathEntry); + if (javaLibraryPath.length() > 0) + javaLibraryPath.append(File.pathSeparator); + javaLibraryPath.append(jniLibraryPathEntry); + } + + File sharedLibraryPathEntry = new File(project.getBasedir(), + "target/nar/lib/" + getAOL() + "/shared"); + if (sharedLibraryPathEntry.exists()) { + getLog().debug( + "Adding library directory to java.library.path: " + + sharedLibraryPathEntry); + if (javaLibraryPath.length() > 0) + javaLibraryPath.append(File.pathSeparator); + javaLibraryPath.append(sharedLibraryPathEntry); + } + + // add jar file to classpath, as one may want to read a + // properties file for artifactId and version + String jarFile = "target/" + project.getArtifactId() + "-" + + project.getVersion() + ".jar"; + getLog().debug("Adding to surefire test classpath: " + jarFile); + surefireBooter.addClassPathUrl(jarFile); + } + + List dependencies = getNarManager().getNarDependencies("test"); + for (Iterator i = dependencies.iterator(); i.hasNext();) { + NarArtifact dependency = (NarArtifact) i.next(); + // FIXME this should be overridable + // NarInfo info = dependency.getNarInfo(); + // String binding = info.getBinding(getAOL(), Library.STATIC); + // NOTE: fixed to shared, jni + String[] bindings = { Library.SHARED, Library.JNI }; + for (int j = 0; j < bindings.length; j++) { + String binding = bindings[j]; + if (!binding.equals(Library.STATIC)) { + File depLibPathEntry = new File(getNarManager() + .getNarFile(dependency).getParent(), "nar/lib/" + + getAOL() + "/" + binding); + if (depLibPathEntry.exists()) { + getLog().debug( + "Adding dependency directory to java.library.path: " + + depLibPathEntry); + if (javaLibraryPath.length() > 0) + javaLibraryPath.append(File.pathSeparator); + javaLibraryPath.append(depLibPathEntry); + } + } + } + } + + // add final javalibrary path + if (javaLibraryPath.length() > 0) { + // NOTE java.library.path only works for the jni lib itself, and + // not for its dependent shareables. + // NOTE: java.library.path does not work with arguments with + // spaces as + // SureFireBooter splits the line in parts and then quotes + // it wrongly + NarUtil.addLibraryPathToEnv(javaLibraryPath.toString(), environmentVariables, getOS()); + } + + // necessary to find WinSxS + if (getOS().equals(OS.WINDOWS)) { + environmentVariables.put("SystemRoot", NarUtil.getEnv("SystemRoot", "SystemRoot", "C:\\Windows")); + } + // ENDFREEHEP + + fork.setArgLine(argLine); + + fork.setEnvironmentVariables(environmentVariables); + + if (getLog().isDebugEnabled()) { + showMap(environmentVariables, "environment variable"); + + fork.setDebug(true); + } + } + + surefireBooter.setRedirectTestOutputToFile(redirectTestOutputToFile); + + surefireBooter.setForkConfiguration(fork); + + surefireBooter.setChildDelegation(childDelegation); + + surefireBooter.setReportsDirectory(reportsDirectory); + + surefireBooter.setUseSystemClassLoader(useSystemClassLoader); + + addReporters(surefireBooter, fork.isForking()); + + return surefireBooter; + } + + private void showMap(Map map, String setting) { + for (Iterator i = map.keySet().iterator(); i.hasNext();) { + String key = (String) i.next(); + String value = (String) map.get(key); + getLog().debug( + "Setting " + setting + " [" + key + "]=[" + value + "]"); + } + } + + private void addProvider(SurefireBooter surefireBooter, String provider, + String version, Artifact filteredArtifact) + throws ArtifactNotFoundException, ArtifactResolutionException { + Artifact providerArtifact = artifactFactory.createDependencyArtifact( + "org.apache.maven.surefire", provider, VersionRange + .createFromVersion(version), "jar", null, + Artifact.SCOPE_TEST); + ArtifactResolutionResult result = resolveArtifact(filteredArtifact, + providerArtifact); + + for (Iterator i = result.getArtifacts().iterator(); i.hasNext();) { + Artifact artifact = (Artifact) i.next(); + + getLog().debug( + "Adding to surefire test classpath: " + + artifact.getFile().getAbsolutePath()); + + surefireBooter.addSurefireClassPathUrl(artifact.getFile() + .getAbsolutePath()); + } + } + + private ArtifactResolutionResult resolveArtifact(Artifact filteredArtifact, + Artifact providerArtifact) throws ArtifactResolutionException, + ArtifactNotFoundException { + ArtifactFilter filter = null; + if (filteredArtifact != null) { + filter = new ExcludesArtifactFilter(Collections + .singletonList(filteredArtifact.getGroupId() + ":" + + filteredArtifact.getArtifactId())); + } + + Artifact originatingArtifact = artifactFactory.createBuildArtifact( + "dummy", "dummy", "1.0", "jar"); + + // FREEHEP, use access method rather than "localRepository" field. + return artifactResolver.resolveTransitively(Collections + .singleton(providerArtifact), originatingArtifact, + getLocalRepository(), remoteRepositories, metadataSource, + filter); + } + + private void addArtifact(SurefireBooter surefireBooter, + Artifact surefireArtifact) throws ArtifactNotFoundException, + ArtifactResolutionException { + ArtifactResolutionResult result = resolveArtifact(null, + surefireArtifact); + + for (Iterator i = result.getArtifacts().iterator(); i.hasNext();) { + Artifact artifact = (Artifact) i.next(); + + getLog().debug( + "Adding to surefire booter test classpath: " + + artifact.getFile().getAbsolutePath()); + + surefireBooter.addSurefireBootClassPathUrl(artifact.getFile() + .getAbsolutePath()); + } + } + + protected void processSystemProperties(boolean setInSystem) { + if (systemProperties == null) { + systemProperties = new Properties(); + } + + originalSystemProperties = (Properties) System.getProperties().clone(); + + systemProperties.setProperty("basedir", basedir.getAbsolutePath()); + + // FREEHEP, use access method rather than "localRepository" field. + systemProperties.setProperty("localRepository", getLocalRepository() + .getBasedir()); + + if (setInSystem) { + // Add all system properties configured by the user + Iterator iter = systemProperties.keySet().iterator(); + + while (iter.hasNext()) { + String key = (String) iter.next(); + + String value = systemProperties.getProperty(key); + + System.setProperty(key, value); + } + } + } + + /** + * <p> + * Adds Reporters that will generate reports with different formatting. + * <p> + * The Reporter that will be added will be based on the value of the + * parameter useFile, reportFormat, and printSummary. + * + * @param surefireBooter + * The surefire booter that will run tests. + * @param forking + */ + private void addReporters(SurefireBooter surefireBooter, boolean forking) { + Boolean trimStackTrace = Boolean.valueOf(this.trimStackTrace); + if (useFile) { + if (printSummary) { + if (forking) { + surefireBooter.addReport(ForkingConsoleReporter.class + .getName(), new Object[] { trimStackTrace }); + } else { + surefireBooter.addReport(ConsoleReporter.class.getName(), + new Object[] { trimStackTrace }); + } + } + + if (BRIEF_REPORT_FORMAT.equals(reportFormat)) { + surefireBooter.addReport(BriefFileReporter.class.getName(), + new Object[] { reportsDirectory, trimStackTrace }); + } else if (PLAIN_REPORT_FORMAT.equals(reportFormat)) { + surefireBooter.addReport(FileReporter.class.getName(), + new Object[] { reportsDirectory, trimStackTrace }); + } + } else { + if (BRIEF_REPORT_FORMAT.equals(reportFormat)) { + surefireBooter.addReport(BriefConsoleReporter.class.getName(), + new Object[] { trimStackTrace }); + } else if (PLAIN_REPORT_FORMAT.equals(reportFormat)) { + surefireBooter.addReport(DetailedConsoleReporter.class + .getName(), new Object[] { trimStackTrace }); + } + } + + if (!disableXmlReport) { + surefireBooter.addReport(XMLReporter.class.getName(), new Object[] { + reportsDirectory, trimStackTrace }); + } + } + + /** + * @return SurefirePlugin Returns the skipExec. + */ + public boolean isSkipExec() { + return this.skipExec; + } + + /** + * @param skipExec + * the skipExec to set + */ + public void setSkipExec(boolean skipExec) { + this.skipExec = skipExec; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarJavahMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarJavahMojo.java new file mode 100644 index 0000000..582e0ad --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarJavahMojo.java @@ -0,0 +1,24 @@ +// Copyright FreeHEP, 2005. +package org.freehep.maven.nar; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + * Compiles class files into c/c++ headers using "javah". + * Any class file that contains methods that were declared + * "native" will be run through javah. + * + * @goal nar-javah + * @phase compile + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarJavahMojo.java eeac31f37379 2007/07/24 04:02:00 duns $ + */ +public class NarJavahMojo extends AbstractCompileMojo { + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) return; + + getJavah().execute(); + } +}
\ No newline at end of file diff --git a/src/main/java/org/apache/maven/plugin/nar/NarLogger.java b/src/main/java/org/apache/maven/plugin/nar/NarLogger.java new file mode 100644 index 0000000..9836808 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarLogger.java @@ -0,0 +1,76 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import org.apache.maven.plugin.logging.Log; +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; + +/** + * Logger to connect the Ant logging to the Maven logging. + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarLogger.java 9589202406dd 2007/07/23 17:42:54 duns $ + */ +public class NarLogger implements BuildListener { + + private Log log; + + public NarLogger(Log log) { + this.log = log; + } + + public void buildStarted(BuildEvent event) { + } + + public void buildFinished(BuildEvent event) { + } + + public void targetStarted(BuildEvent event) { + } + + public void targetFinished(BuildEvent event) { + } + + public void taskStarted(BuildEvent event) { + } + + public void taskFinished(BuildEvent event) { + } + + public void messageLogged(BuildEvent event) { + String msg = event.getMessage(); + switch (event.getPriority()) { + case Project.MSG_ERR: + if (msg.indexOf("ar: creating archive") >= 0) { + log.debug(msg); + } else if (msg.indexOf("warning") >= 0) { + log.warn(msg); + } else { + log.error(msg); + } + break; + case Project.MSG_WARN: + log.warn(msg); + break; + case Project.MSG_INFO: + if ((msg.indexOf("files were compiled") >= 0) || (msg.indexOf("Linking...") >= 0)) { + log.info(msg); + } else if (msg.indexOf("error") >= 0) { + log.error(msg); + } else if (msg.indexOf("warning") >= 0) { + log.warn(msg); + } else { + log.debug(msg); + } + break; + case Project.MSG_VERBOSE: + log.debug(msg); + break; + default: + case Project.MSG_DEBUG: + log.debug(msg); + break; + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarManager.java b/src/main/java/org/apache/maven/plugin/nar/NarManager.java new file mode 100644 index 0000000..16dda1d --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarManager.java @@ -0,0 +1,363 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.LinkedList; +import java.util.jar.JarFile; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactNotFoundException; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolver; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.archiver.ArchiverException; +import org.codehaus.plexus.archiver.UnArchiver; +import org.codehaus.plexus.archiver.manager.ArchiverManager; +import org.codehaus.plexus.archiver.manager.NoSuchArchiverException; +import org.codehaus.plexus.util.FileUtils; + +public class NarManager { + + private Log log; + + private MavenProject project; + + private ArtifactRepository repository; + + private AOL defaultAOL; + private String linkerName; + + private String[] narTypes = { "noarch", Library.STATIC, Library.SHARED, Library.JNI, Library.PLUGIN }; + + public NarManager(Log log, ArtifactRepository repository, + MavenProject project, String architecture, String os, Linker linker) + throws MojoFailureException { + this.log = log; + this.repository = repository; + this.project = project; + this.defaultAOL = NarUtil.getAOL(architecture, os, linker, null); + this.linkerName = NarUtil.getLinkerName(architecture, os, linker); + } + + /** + * Returns dependencies which are dependent on NAR files (i.e. contain + * NarInfo) + */ + public List/* <NarArtifact> */getNarDependencies(String scope) + throws MojoExecutionException { + List narDependencies = new LinkedList(); + for (Iterator i = getDependencies(scope).iterator(); i.hasNext();) { + Artifact dependency = (Artifact) i.next(); + log.debug("Examining artifact for NarInfo: "+dependency); + + NarInfo narInfo = getNarInfo(dependency); + if (narInfo != null) { + log.debug(" - added as NarDependency"); + narDependencies.add(new NarArtifact(dependency, narInfo)); + } + } + return narDependencies; + } + + /** + * Returns all NAR dependencies by type: noarch, static, dynamic, jni, + * plugin. + * + * @throws MojoFailureException + */ + public Map/* <String, List<AttachedNarArtifact>> */getAttachedNarDependencyMap( + String scope) throws MojoExecutionException, MojoFailureException { + Map attachedNarDependencies = new HashMap(); + for (Iterator i = getNarDependencies(scope).iterator(); i.hasNext();) { + Artifact dependency = (Artifact) i.next(); + for (int j = 0; j < narTypes.length; j++) { + List artifactList = getAttachedNarDependencies(dependency, + defaultAOL, narTypes[j]); + if (artifactList != null) + attachedNarDependencies.put(narTypes[j], artifactList); + } + } + return attachedNarDependencies; + } + + public List/* <AttachedNarArtifact> */getAttachedNarDependencies( + List/* <NarArtifacts> */narArtifacts) + throws MojoExecutionException, MojoFailureException { + return getAttachedNarDependencies(narArtifacts, null); + } + + public List/* <AttachedNarArtifact> */getAttachedNarDependencies( + List/* <NarArtifacts> */narArtifacts, String classifier) + throws MojoExecutionException, MojoFailureException { + AOL aol = null; + String type = null; + if (classifier != null) { + int dash = classifier.lastIndexOf('-'); + if (dash < 0) { + aol = new AOL(classifier); + type = null; + } else { + aol = new AOL(classifier.substring(0, dash)); + type = classifier.substring(dash + 1); + } + } + return getAttachedNarDependencies(narArtifacts, aol, type); + } + + /** + * Returns a list of all attached nar dependencies for a specific binding + * and "noarch", but not where "local" is specified + * + * @param scope + * compile, test, runtime, .... + * @param aol + * either a valid aol, noarch or null. In case of null both the + * default getAOL() and noarch dependencies are returned. + * @param type + * noarch, static, shared, jni, or null. In case of null the + * default binding found in narInfo is used. + * @return + * @throws MojoExecutionException + * @throws MojoFailureException + */ + public List/* <AttachedNarArtifact> */getAttachedNarDependencies( + List/* <NarArtifacts> */narArtifacts, AOL aol, String type) + throws MojoExecutionException, MojoFailureException { + boolean noarch = false; + if (aol == null) { + noarch = true; + aol = defaultAOL; + } + + List artifactList = new ArrayList(); + for (Iterator i = narArtifacts.iterator(); i.hasNext();) { + Artifact dependency = (Artifact) i.next(); + NarInfo narInfo = getNarInfo(dependency); + if (noarch) { + artifactList.addAll(getAttachedNarDependencies(dependency, + null, "noarch")); + } + + // use preferred binding, unless non existing. + String binding = narInfo.getBinding(aol, type != null ? type + : "static"); + + // FIXME kludge, but does not work anymore since AOL is now a class + if (aol.equals("noarch")) { + // FIXME no handling of local + artifactList.addAll(getAttachedNarDependencies(dependency, + null, "noarch")); + } else { + artifactList.addAll(getAttachedNarDependencies(dependency, aol, + binding)); + } + } + return artifactList; + } + + private List/* <AttachedNarArtifact> */getAttachedNarDependencies( + Artifact dependency, AOL aol, String type) + throws MojoExecutionException, MojoFailureException { + log.debug("GetNarDependencies for " + dependency + ", aol: " + aol + ", type: " + type); + List artifactList = new ArrayList(); + NarInfo narInfo = getNarInfo(dependency); + String[] nars = narInfo.getAttachedNars(aol, type); + // FIXME Move this to NarInfo.... + if (nars != null) { + for (int j = 0; j < nars.length; j++) { + log.debug(" Checking: " + nars[j]); + if (nars[j].equals("")) + continue; + String[] nar = nars[j].split(":", 5); + if (nar.length >= 4) { + try { + String groupId = nar[0].trim(); + String artifactId = nar[1].trim(); + String ext = nar[2].trim(); + String classifier = nar[3].trim(); + // translate for instance g++ to gcc... + aol = narInfo.getAOL(aol); + if (aol != null) { + classifier = NarUtil.replace("${aol}", aol.toString(), + classifier); + } + String version = nar.length >= 5 ? nar[4].trim() + : dependency.getVersion(); + artifactList.add(new AttachedNarArtifact(groupId, + artifactId, version, dependency.getScope(), + ext, classifier, dependency.isOptional())); + } catch (InvalidVersionSpecificationException e) { + throw new MojoExecutionException( + "Error while reading nar file for dependency " + + dependency, e); + } + } else { + log.warn("nars property in " + dependency.getArtifactId() + + " contains invalid field: '" + nars[j] + + "' for type: " + type); + } + } + } + return artifactList; + } + + public NarInfo getNarInfo(Artifact dependency) + throws MojoExecutionException { + // FIXME reported to maven developer list, isSnapshot changes behaviour + // of getBaseVersion, called in pathOf. + if (dependency.isSnapshot()) + ; + + File file = new File(repository.getBasedir(), repository + .pathOf(dependency)); + JarFile jar = null; + try { + jar = new JarFile(file); + NarInfo info = new NarInfo(dependency.getGroupId(), dependency + .getArtifactId(), dependency.getVersion(), log); + if (!info.exists(jar)) + return null; + info.read(jar); + return info; + } catch (IOException e) { + throw new MojoExecutionException("Error while reading " + file, e); + } finally { + if (jar != null) { + try { + jar.close(); + } catch (IOException e) { + // ignore + } + } + } + } + + public File getNarFile(Artifact dependency) throws MojoFailureException { + // FIXME reported to maven developer list, isSnapshot changes behaviour + // of getBaseVersion, called in pathOf. + if (dependency.isSnapshot()) + ; + return new File(repository.getBasedir(), NarUtil.replace("${aol}", + defaultAOL.toString(), repository.pathOf(dependency))); + } + + private List getDependencies(String scope) { + if (scope.equals("test")) { + return project.getTestArtifacts(); + } else if (scope.equals("runtime")) { + return project.getRuntimeArtifacts(); + } + return project.getCompileArtifacts(); + } + + public void downloadAttachedNars(List/* <NarArtifacts> */narArtifacts, + List remoteRepositories, ArtifactResolver resolver, + String classifier) throws MojoExecutionException, + MojoFailureException { + // FIXME this may not be the right way to do this.... -U ignored and + // also SNAPSHOT not used + List dependencies = getAttachedNarDependencies(narArtifacts, classifier); + for (Iterator i = dependencies.iterator(); i.hasNext();) { + Artifact dependency = (Artifact) i.next(); + try { + log.debug("Resolving " + dependency); + resolver.resolve(dependency, remoteRepositories, repository); + } catch (ArtifactNotFoundException e) { + String message = "nar not found " + dependency.getId(); + throw new MojoExecutionException(message, e); + } catch (ArtifactResolutionException e) { + String message = "nar cannot resolve " + dependency.getId(); + throw new MojoExecutionException(message, e); + } + } + } + + public void unpackAttachedNars(List/* <NarArtifacts> */narArtifacts, + ArchiverManager manager, String classifier, String os) + throws MojoExecutionException, MojoFailureException { + log.debug("Unpack called for OS: "+os+", classifier: "+classifier+" for NarArtifacts {"); + for (Iterator i = narArtifacts.iterator(); i.hasNext(); ) { + log.debug(" - "+((NarArtifact)i.next())); + } + log.debug("}"); + // FIXME, kludge to get to download the -noarch, based on classifier + List dependencies = getAttachedNarDependencies(narArtifacts, classifier); + for (Iterator i = dependencies.iterator(); i.hasNext();) { + Artifact dependency = (Artifact) i.next(); + log.debug("Unpack " + dependency); + File file = getNarFile(dependency); + File narLocation = new File(file.getParentFile(), "nar"); + File flagFile = new File(narLocation, FileUtils.basename(file + .getPath(), "." + AbstractNarMojo.NAR_EXTENSION) + + ".flag"); + + boolean process = false; + if (!narLocation.exists()) { + narLocation.mkdirs(); + process = true; + } else if (!flagFile.exists()) { + process = true; + } else if (file.lastModified() > flagFile.lastModified()) { + process = true; + } + + if (process) { + try { + unpackNar(manager, file, narLocation); + if (!NarUtil.getOS(os).equals("Windows")) { + NarUtil.makeExecutable(new File(narLocation, "bin/"+defaultAOL), + log); + // FIXME clumsy + if (defaultAOL.hasLinker("g++")) { + NarUtil.makeExecutable(new File(narLocation, "bin/"+NarUtil.replace("g++", "gcc", defaultAOL.toString())), + log); + } + } + if (linkerName.equals("gcc") || linkerName.equals("g++")) { + NarUtil.runRanlib(new File(narLocation, "lib/"+defaultAOL), log); + // FIXME clumsy + if (defaultAOL.hasLinker("g++")) { + NarUtil.runRanlib(new File(narLocation, "lib/"+NarUtil.replace("g++", "gcc", defaultAOL.toString())), + log); + } + } + FileUtils.fileDelete(flagFile.getPath()); + FileUtils.fileWrite(flagFile.getPath(), ""); + } catch (IOException e) { + log.warn("Cannot create flag file: " + flagFile.getPath()); + } + } + } + } + + private void unpackNar(ArchiverManager manager, File file, File location) + throws MojoExecutionException { + try { + UnArchiver unArchiver; + unArchiver = manager.getUnArchiver(AbstractNarMojo.NAR_ROLE_HINT); + unArchiver.setSourceFile(file); + unArchiver.setDestDirectory(location); + unArchiver.extract(); + } catch (IOException e) { + throw new MojoExecutionException("Error unpacking file: " + file + + " to: " + location, e); + } catch (NoSuchArchiverException e) { + throw new MojoExecutionException("Error unpacking file: " + file + + " to: " + location, e); + } catch (ArchiverException e) { + throw new MojoExecutionException("Error unpacking file: " + file + + " to: " + location, e); + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarPackageMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarPackageMojo.java new file mode 100644 index 0000000..1009679 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarPackageMojo.java @@ -0,0 +1,135 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProjectHelper; +import org.codehaus.plexus.archiver.Archiver; +import org.codehaus.plexus.archiver.ArchiverException; +import org.codehaus.plexus.archiver.zip.ZipArchiver; + +/** + * Jars up the NAR files. + * + * @goal nar-package + * @phase package + * @requiresProject + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarPackageMojo.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public class NarPackageMojo extends AbstractCompileMojo { + + /** + * Used for attaching the artifact in the project + * + * @component + */ + private MavenProjectHelper projectHelper; + + private File narDirectory; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) + return; + + // FIX for NARPLUGIN-??? where -DupdateReleaseInfo copies to a .nar file + getMavenProject().getArtifact().setArtifactHandler( + new NarArtifactHandler()); + + narDirectory = new File(getOutputDirectory(), "nar"); + + // noarch + String include = "include"; + if (new File(narDirectory, include).exists()) { + attachNar("include", null, NAR_NO_ARCH); + } + + // create nar with binaries + String bin = "bin"; + String[] binAOLs = new File(narDirectory, bin).list(); + for (int i = 0; i < (binAOLs != null ? binAOLs.length : 0); i++) { + attachNar(bin + "/" + binAOLs[i], binAOLs[i], bin); + } + + // create nars for each type of library (static, shared). + String bindingType = null; + for (Iterator i = getLibraries().iterator(); i.hasNext();) { + Library library = (Library) i.next(); + String type = library.getType(); + if (bindingType == null) + bindingType = type; + + // create nar with libraries + String lib = "lib"; + String[] libAOLs = new File(narDirectory, lib).list(); + for (int j = 0; j < (libAOLs != null ? libAOLs.length : 0); j++) { + attachNar(lib + "/" + libAOLs[j] + "/" + type, libAOLs[j], type); + } + } + + // override binding if not set + if (getNarInfo().getBinding(null, null) == null) { + getNarInfo().setBinding(null, bindingType != null ? bindingType + : Library.NONE); + } + + try { + File propertiesDir = new File(getOutputDirectory(), "classes/META-INF/nar/" + + getMavenProject().getGroupId() + "/" + getMavenProject().getArtifactId()); + if (!propertiesDir.exists()) { + propertiesDir.mkdirs(); + } + File propertiesFile = new File(propertiesDir, NarInfo.NAR_PROPERTIES); + getNarInfo().writeToFile(propertiesFile); + } catch (IOException ioe) { + throw new MojoExecutionException( + "Cannot write nar properties file", ioe); + } + } + + private void attachNar(String dir, String aol, String type) + throws MojoExecutionException { + File libFile = new File(getOutputDirectory(), getFinalName() + "-" + + (aol != null ? aol + "-" : "") + type + "." + NAR_EXTENSION); + nar(libFile, narDirectory, new String[] { dir }); + projectHelper.attachArtifact(getMavenProject(), NAR_TYPE, + (aol != null ? aol + "-" : "") + type, libFile); + getNarInfo().setNar(null, type, getMavenProject().getGroupId() + ":" + + getMavenProject().getArtifactId() + ":" + NAR_TYPE + ":" + + (aol != null ? "${aol}-" : "") + type); + + } + + private void nar(File nar, File dir, String[] dirs) + throws MojoExecutionException { + try { + if (nar.exists()) { + nar.delete(); + } + + Archiver archiver = new ZipArchiver(); + // seems to return same archiver all the time + // archiverManager.getArchiver(NAR_ROLE_HINT); + for (int i = 0; i < dirs.length; i++) { + String[] includes = new String[] { dirs[i] + "/**" }; + archiver.addDirectory(dir, includes, null); + } + archiver.setDestFile(nar); + archiver.createArchive(); + } catch (ArchiverException e) { + throw new MojoExecutionException( + "Error while creating NAR archive.", e); + // } catch (NoSuchArchiverException e) { + // throw new MojoExecutionException("Error while creating NAR + // archive.", e ); + } catch (IOException e) { + throw new MojoExecutionException( + "Error while creating NAR archive.", e); + } + } + +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarResourcesMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarResourcesMojo.java new file mode 100644 index 0000000..ee4d712 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarResourcesMojo.java @@ -0,0 +1,162 @@ +// Copyright FreeHEP, 2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.codehaus.plexus.archiver.ArchiverException; +import org.codehaus.plexus.archiver.UnArchiver; +import org.codehaus.plexus.archiver.manager.ArchiverManager; +import org.codehaus.plexus.archiver.manager.NoSuchArchiverException; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.SelectorUtils; + +/** + * Copies any resources, including AOL specific distributions, to the target + * area for packaging + * + * @goal nar-resources + * @phase process-resources + * @requiresProject + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarResourcesMojo.java 2126b860c9c5 2007/07/31 23:19:30 duns $ + */ +public class NarResourcesMojo extends AbstractCompileMojo { + + /** + * Directory for nar resources. Defaults to src/nar/resources + * + * @parameter expression="${basedir}/src/nar/resources" + * @required + */ + private File resourceDirectory; + + /** + * Binary directory (relative to ${resourceDirectory}/aol/${aol} + * + * @parameter expression="bin" + * @required + */ + private String resourceBinDir; + + /** + * Include directory (relative to ${resourceDirectory}/aol/${aol} + * + * @parameter expression="include" + * @required + */ + private String resourceIncludeDir; + + /** + * Library directory (relative to ${resourceDirectory}/aol/${aol} + * + * @parameter expression="lib" + * @required + */ + private String resourceLibDir; + + /** + * To look up Archiver/UnArchiver implementations + * + * @parameter expression="${component.org.codehaus.plexus.archiver.manager.ArchiverManager}" + * @required + */ + private ArchiverManager archiverManager; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) + return; + + // scan for AOLs + File aolDir = new File(resourceDirectory, "aol"); + if (aolDir.exists()) { + String[] aols = aolDir.list(); + for (int i = 0; i < aols.length; i++) { + boolean ignore = false; + for (Iterator j = FileUtils.getDefaultExcludesAsList() + .iterator(); j.hasNext();) { + String exclude = (String)j.next(); + if (SelectorUtils.matchPath(exclude.replace('/', File.separatorChar), aols[i])) { + ignore = true; + break; + } + } + if (!ignore) { + copyResources(new File(aolDir, aols[i])); + } + } + } + } + + private void copyResources(File aolDir) throws MojoExecutionException, + MojoFailureException { + String aol = aolDir.getName(); + int copied = 0; + try { + // copy headers + File includeDir = new File(aolDir, resourceIncludeDir); + if (includeDir.exists()) { + File includeDstDir = new File(getTargetDirectory(), "include"); + copied += NarUtil.copyDirectoryStructure(includeDir, + includeDstDir, null, NarUtil.DEFAULT_EXCLUDES); + } + + // copy binaries + File binDir = new File(aolDir, resourceBinDir); + if (binDir.exists()) { + File binDstDir = new File(getTargetDirectory(), "bin"); + binDstDir = new File(binDstDir, aol); + + copied += NarUtil.copyDirectoryStructure(binDir, binDstDir, + null, NarUtil.DEFAULT_EXCLUDES); + } + + // copy libraries + File libDir = new File(aolDir, resourceLibDir); + if (libDir.exists()) { + // create all types of libs + for (Iterator i = getLibraries().iterator(); i.hasNext();) { + Library library = (Library) i.next(); + String type = library.getType(); + File libDstDir = new File(getTargetDirectory(), "lib"); + libDstDir = new File(libDstDir, aol); + libDstDir = new File(libDstDir, type); + + // filter files for lib + String includes = "**/*." + + NarUtil.getDefaults().getProperty( + NarUtil.getAOLKey(aol) + "." + type + + ".extension"); + copied += NarUtil.copyDirectoryStructure(libDir, libDstDir, + includes, NarUtil.DEFAULT_EXCLUDES); + } + } + + // unpack jar files + File classesDirectory = new File(getOutputDirectory(),"classes"); + classesDirectory.mkdirs(); + List jars = FileUtils.getFiles(aolDir, "**/*.jar", null); + for (Iterator i=jars.iterator(); i.hasNext(); ) { + File jar = (File)i.next(); + getLog().debug("Unpacking jar "+jar); + UnArchiver unArchiver; + unArchiver = archiverManager.getUnArchiver(AbstractNarMojo.NAR_ROLE_HINT); + unArchiver.setSourceFile(jar); + unArchiver.setDestDirectory(classesDirectory); + unArchiver.extract(); + } + } catch (IOException e) { + throw new MojoExecutionException("NAR: Could not copy resources", e); + } catch (NoSuchArchiverException e) { + throw new MojoExecutionException("NAR: Could not find archiver", e); + } catch (ArchiverException e) { + throw new MojoExecutionException("NAR: Could not unarchive jar file", e); + } + getLog().info("Copied " + copied + " resources for " + aol); + } + +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarSystemGenerate.java b/src/main/java/org/apache/maven/plugin/nar/NarSystemGenerate.java new file mode 100644 index 0000000..f1d9e7e --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarSystemGenerate.java @@ -0,0 +1,79 @@ +// Copyright FreeHEP, 2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + * Generates a NarSystem class with static methods to use inside the java part + * of the library. + * + * @goal nar-system-generate + * @phase generate-sources + * @requiresProject + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarSystemGenerate.java d43b38443d0b 2007/09/13 18:31:01 duns $ + */ +public class NarSystemGenerate extends AbstractCompileMojo { + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) + return; + + // get packageName if specified for JNI. + String packageName = null; + String narSystemName = null; + File narSystemDirectory = null; + for (Iterator i = getLibraries().iterator(); i.hasNext() + && (packageName == null);) { + Library library = (Library) i.next(); + if (library.getType().equals(Library.JNI)) { + packageName = library.getNarSystemPackage(); + narSystemName = library.getNarSystemName(); + narSystemDirectory = library.getNarSystemDirectory(); + } + } + + if (packageName == null) + return; + + // make sure destination is there + narSystemDirectory.mkdirs(); + + getMavenProject().addCompileSourceRoot(narSystemDirectory.getPath()); + + File fullDir = new File(narSystemDirectory, packageName.replace('.', '/')); + fullDir.mkdirs(); + + File narSystem = new File(fullDir, narSystemName + ".java"); + try { + FileOutputStream fos = new FileOutputStream(narSystem); + PrintWriter p = new PrintWriter(fos); + p.println("// DO NOT EDIT: Generated by NarSystemGenerate."); + p.println("package " + packageName + ";"); + p.println(""); + p.println("public class NarSystem {"); + p.println(""); + p.println(" private NarSystem() {"); + p.println(" }"); + p.println(""); + p.println(" public static void loadLibrary() {"); + p.println(" System.loadLibrary(\"" + + getMavenProject().getArtifactId() + "-" + + getMavenProject().getVersion() + "\");"); + p.println(" }"); + p.println("}"); + p.close(); + fos.close(); + } catch (IOException e) { + throw new MojoExecutionException("Could not write '" + + narSystemName + "'", e); + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarTestCompileMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarTestCompileMojo.java new file mode 100644 index 0000000..e55a4ad --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarTestCompileMojo.java @@ -0,0 +1,225 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.OutputTypeEnum; +import net.sf.antcontrib.cpptasks.RuntimeType; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; + +/** + * Compiles native test source files. + * + * @goal nar-testCompile + * @phase test-compile + * @requiresDependencyResolution test + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarTestCompileMojo.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public class NarTestCompileMojo extends AbstractCompileMojo { + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) + return; + + // make sure destination is there + getTargetDirectory().mkdirs(); + + for (Iterator i = getTests().iterator(); i.hasNext();) { + createTest(getAntProject(), (Test) i.next()); + } + } + + private void createTest(Project antProject, Test test) + throws MojoExecutionException, MojoFailureException { + String type = "test"; + + // configure task + CCTask task = new CCTask(); + task.setProject(antProject); + + // outtype + OutputTypeEnum outTypeEnum = new OutputTypeEnum(); + outTypeEnum.setValue(Library.EXECUTABLE); + task.setOuttype(outTypeEnum); + + // outDir + File outDir = new File(getTargetDirectory(), "bin"); + outDir = new File(outDir, getAOL().toString()); + outDir.mkdirs(); + + // outFile + File outFile = new File(outDir, test.getName()); + getLog().debug("NAR - output: '" + outFile + "'"); + task.setOutfile(outFile); + + // object directory + File objDir = new File(getTargetDirectory(), "obj"); + objDir = new File(objDir, getAOL().toString()); + objDir.mkdirs(); + task.setObjdir(objDir); + + // failOnError, libtool + task.setFailonerror(failOnError(getAOL())); + task.setLibtool(useLibtool(getAOL())); + + // runtime + RuntimeType runtimeType = new RuntimeType(); + runtimeType.setValue(getRuntime(getAOL())); + task.setRuntime(runtimeType); + + // add C++ compiler + task.addConfiguredCompiler(getCpp().getCompiler(type, test.getName())); + + // add C compiler + task.addConfiguredCompiler(getC().getCompiler(type, test.getName())); + + // add Fortran compiler + task.addConfiguredCompiler(getFortran().getCompiler(type, + test.getName())); + + // add java include paths + getJava().addIncludePaths(task, type); + + // add dependency include paths + for (Iterator i = getNarManager().getNarDependencies("test").iterator(); i + .hasNext();) { + File include = new File(getNarManager().getNarFile( + (Artifact) i.next()).getParentFile(), "nar/include"); + if (include.exists()) { + task.createIncludePath().setPath(include.getPath()); + } + } + + // add linker + task.addConfiguredLinker(getLinker().getLinker(this, antProject, + getOS(), getAOL().getKey() + "linker.", type)); + + // FIXME hardcoded values + String libName = getFinalName(); + File includeDir = new File(getMavenProject().getBuild().getDirectory(), + "nar/include"); + File libDir = new File(getMavenProject().getBuild().getDirectory(), + "nar/lib/" + getAOL() + "/" + test.getLink()); + + // copy shared library + // FIXME why do we do this ? +/* Removed in alpha-10 + if (test.getLink().equals(Library.SHARED)) { + try { + // defaults are Unix + String libPrefix = NarUtil.getDefaults().getProperty( + getAOLKey() + "shared.prefix", "lib"); + String libExt = NarUtil.getDefaults().getProperty( + getAOLKey() + "shared.extension", "so"); + File copyDir = new File(getTargetDirectory(), (getOS().equals( + "Windows") ? "bin" : "lib") + + "/" + getAOL() + "/" + test.getLink()); + FileUtils.copyFileToDirectory(new File(libDir, libPrefix + + libName + "." + libExt), copyDir); + if (!getOS().equals(OS.WINDOWS)) { + libDir = copyDir; + } + } catch (IOException e) { + throw new MojoExecutionException( + "NAR: Could not copy shared library", e); + } + } +*/ + // FIXME what about copying the other shared libs? + + // add include of this package + if (includeDir.exists()) { + task.createIncludePath().setLocation(includeDir); + } + + // add library of this package + if (libDir.exists()) { + LibrarySet libSet = new LibrarySet(); + libSet.setProject(antProject); + libSet.setLibs(new CUtil.StringArrayBuilder(libName)); + LibraryTypeEnum libType = new LibraryTypeEnum(); + libType.setValue(test.getLink()); + libSet.setType(libType); + libSet.setDir(libDir); + task.addLibset(libSet); + } + + // add dependency libraries + List depLibOrder = getDependencyLibOrder(); + List depLibs = getNarManager().getNarDependencies("test"); + + // reorder the libraries that come from the nar dependencies + // to comply with the order specified by the user + if ((depLibOrder != null) && !depLibOrder.isEmpty()) { + + List tmp = new LinkedList(); + + for (Iterator i = depLibOrder.iterator(); i.hasNext();) { + + String depToOrderName = (String)i.next(); + + for (Iterator j = depLibs.iterator(); j.hasNext();) { + + NarArtifact dep = (NarArtifact)j.next(); + String depName = dep.getGroupId() + ":" + dep.getArtifactId(); + + if (depName.equals(depToOrderName)) { + + tmp.add(dep); + j.remove(); + } + } + } + + tmp.addAll(depLibs); + depLibs = tmp; + } + + for (Iterator i = depLibs.iterator(); i.hasNext();) { + + Artifact dependency = (Artifact) i.next(); + // FIXME: this should be preferred binding + File lib = new File(getNarManager().getNarFile(dependency) + .getParentFile(), "nar/lib/" + getAOL() + "/" + + test.getLink()); + if (lib.exists()) { + LibrarySet libset = new LibrarySet(); + libset.setProject(antProject); + libset.setLibs(new CUtil.StringArrayBuilder(dependency + .getArtifactId() + + "-" + dependency.getVersion())); + libset.setDir(lib); + task.addLibset(libset); + } + } + + // Add JVM to linker + getJava().addRuntime(task, getJavaHome(getAOL()), getOS(), + getAOL().getKey() + ".java."); + + // execute + try { + task.execute(); + } catch (BuildException e) { + throw new MojoExecutionException("NAR: Test-Compile failed", e); + } + } + + protected File getTargetDirectory() { + return new File(getMavenProject().getBuild().getDirectory(), "test-nar"); + } + +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarTestMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarTestMojo.java new file mode 100644 index 0000000..62e721e --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarTestMojo.java @@ -0,0 +1,148 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.StringUtils; + +/** + * Tests NAR files. Runs Native Tests and executables if produced. + * + * @goal nar-test + * @phase test + * @requiresProject + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarTestMojo.java 51709c87671c 2007/08/08 22:49:17 duns $ + */ +public class NarTestMojo extends AbstractCompileMojo { + + /** + * The classpath elements of the project being tested. + * + * @parameter expression="${project.testClasspathElements}" + * @required + * @readonly + */ + private List classpathElements; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) + return; + + // run all tests + for (Iterator i = getTests().iterator(); i.hasNext();) { + runTest((Test) i.next()); + } + + for (Iterator i = getLibraries().iterator(); i.hasNext();) { + runExecutable((Library) i.next()); + } + } + + private void runTest(Test test) throws MojoExecutionException, + MojoFailureException { + // run if requested + if (test.shouldRun()) { + String name = "target/test-nar/bin/" + getAOL() + "/" + test.getName(); + getLog().info("Running " + name); + List args = test.getArgs(); + int result = NarUtil.runCommand(getMavenProject() + .getBasedir() + + "/" + name, (String[]) args.toArray(new String[args.size()]), generateEnvironment(test, + getLog()), getLog()); + if (result != 0) + throw new MojoFailureException("Test " + name + + " failed with exit code: " + result+" 0x"+Integer.toHexString(result)); + } + } + + private void runExecutable(Library library) throws MojoExecutionException, + MojoFailureException { + if (library.getType().equals(Library.EXECUTABLE) && library.shouldRun()) { + MavenProject project = getMavenProject(); + String name = "target/nar/bin/" + getAOL() + "/" + + project.getArtifactId(); + getLog().info("Running " + name); + List args = library.getArgs(); + int result = NarUtil.runCommand(project.getBasedir() + + "/" + name, (String[]) args.toArray(new String[args.size()]), generateEnvironment( + library, getLog()), getLog()); + if (result != 0) + throw new MojoFailureException("Test " + name + + " failed with exit code: " + result+" 0x"+Integer.toHexString(result)); + } + } + + protected File getTargetDirectory() { + return new File(getMavenProject().getBuild().getDirectory(), "test-nar"); + } + + private String[] generateEnvironment(Executable exec, Log log) + throws MojoExecutionException, MojoFailureException { + List env = new ArrayList(); + + Set/*<File>*/ sharedPaths = new HashSet(); + + // add all shared libraries of this package + for (Iterator i=getLibraries().iterator(); i.hasNext(); ) { + Library lib = (Library)i.next(); + if (lib.getType().equals(Library.SHARED)) { + sharedPaths.add(new File(getMavenProject().getBasedir(), "target/nar/lib/"+getAOL()+"/"+lib.getType())); + } + } + + // add dependent shared libraries + String classifier = getAOL()+"-shared"; + List narArtifacts = getNarManager().getNarDependencies("compile"); + List dependencies = getNarManager().getAttachedNarDependencies( + narArtifacts, classifier); + for (Iterator d = dependencies.iterator(); d.hasNext();) { + Artifact dependency = (Artifact) d.next(); + getLog().debug("Looking for dependency " + dependency); + + // FIXME reported to maven developer list, isSnapshot + // changes behaviour + // of getBaseVersion, called in pathOf. + if (dependency.isSnapshot()) + ; + + File libDir = new File(getLocalRepository().pathOf(dependency)); + libDir = new File(getLocalRepository().getBasedir(), libDir + .getParent()); + libDir = new File(libDir, "nar/lib/"+getAOL()+"/shared"); + sharedPaths.add(libDir); + } + + // set environment + if (sharedPaths.size() > 0) { + String sharedPath = ""; + for (Iterator i=sharedPaths.iterator(); i.hasNext(); ) { + sharedPath += ((File)i.next()).getPath(); + if (i.hasNext()) sharedPath += File.pathSeparator; + } + + String sharedEnv = NarUtil.addLibraryPathToEnv(sharedPath, null, getOS()); + env.add(sharedEnv); + } + + // necessary to find WinSxS + if (getOS().equals(OS.WINDOWS)) { + env.add("SystemRoot="+NarUtil.getEnv("SystemRoot", "SystemRoot", "C:\\Windows")); + } + + // add CLASSPATH + env.add("CLASSPATH="+StringUtils.join(classpathElements.iterator(), File.pathSeparator)); + + return env.size() > 0 ? (String[]) env.toArray(new String[env.size()]) : null; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarUnArchiver.java b/src/main/java/org/apache/maven/plugin/nar/NarUnArchiver.java new file mode 100644 index 0000000..7a94d60 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarUnArchiver.java @@ -0,0 +1,12 @@ +// Copyright FreeHEP, 2005. +package org.freehep.maven.nar; + +import org.codehaus.plexus.archiver.zip.AbstractZipUnArchiver; + +/** + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarUnArchiver.java eda4d0bbde3d 2007/07/03 16:52:10 duns $ + */ +public class NarUnArchiver extends AbstractZipUnArchiver { +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarUnpackMojo.java b/src/main/java/org/apache/maven/plugin/nar/NarUnpackMojo.java new file mode 100644 index 0000000..eb6b1db --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarUnpackMojo.java @@ -0,0 +1,52 @@ +// Copyright FreeHEP, 2005-2006. +package org.freehep.maven.nar; + +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.codehaus.plexus.archiver.manager.ArchiverManager; + +/** + * Unpacks NAR files. Unpacking happens in the local repository, + * and also sets flags on binaries and corrects static libraries. + * + * @goal nar-unpack + * @phase process-sources + * @requiresProject + * @requiresDependencyResolution + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarUnpackMojo.java eda4d0bbde3d 2007/07/03 16:52:10 duns $ + */ +public class NarUnpackMojo extends AbstractDependencyMojo { + + /** + * List of classifiers which you want unpack. Example ppc-MacOSX-g++, + * x86-Windows-msvc, i386-Linux-g++. + * + * @parameter expression="" + */ + private List classifiers; + + /** + * To look up Archiver/UnArchiver implementations + * + * @parameter expression="${component.org.codehaus.plexus.archiver.manager.ArchiverManager}" + * @required + */ + private ArchiverManager archiverManager; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (shouldSkip()) return; + + List narArtifacts = getNarManager().getNarDependencies("compile"); + if (classifiers == null) { + getNarManager().unpackAttachedNars(narArtifacts, archiverManager, null, getOS()); + } else { + for (Iterator j = classifiers.iterator(); j.hasNext();) { + getNarManager().unpackAttachedNars(narArtifacts, archiverManager, (String) j.next(), getOS()); + } + } + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/NarUtil.java b/src/main/java/org/apache/maven/plugin/nar/NarUtil.java new file mode 100644 index 0000000..c5372b9 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/NarUtil.java @@ -0,0 +1,417 @@ +// Copyright 2005-2007, FreeHEP. +package org.freehep.maven.nar; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Pattern; + +import org.apache.bcel.classfile.ClassFormatException; +import org.apache.bcel.classfile.ClassParser; +import org.apache.bcel.classfile.JavaClass; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.PropertyUtils; +import org.codehaus.plexus.util.cli.Commandline; + +/** + * @author Mark Donszelmann + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/NarUtil.java 0ee9148b7c6a 2007/09/20 18:42:29 duns $ + */ +public class NarUtil { + + private static Properties defaults; + + public static Properties getDefaults() throws MojoFailureException { + // read properties file with defaults + if (defaults == null) { + defaults = PropertyUtils.loadProperties(NarUtil.class + .getResourceAsStream("aol.properties")); + } + if (defaults == null) + throw new MojoFailureException( + "NAR: Could not load default properties file: 'aol.properties'."); + + return defaults; + } + + public static String getOS(String os) { + // adjust OS if not given + if (os == null) { + os = System.getProperty("os.name"); + if (os.startsWith("Windows")) + os = OS.WINDOWS; + if (os.startsWith("windows")) + os = OS.WINDOWS; + if (os.equals("Mac OS X")) + os = OS.MACOSX; + } + return os; + } + + public static String getArchitecture(String architecture) { + return architecture; + } + + public static Linker getLinker(Linker linker) { + if (linker == null) { + linker = new Linker(); + } + return linker; + } + + public static String getLinkerName(String architecture, String os, + Linker linker) throws MojoFailureException { + return getLinker(linker).getName(getDefaults(), + getArchitecture(architecture) + "." + getOS(os) + "."); + } + + public static AOL getAOL(String architecture, String os, Linker linker, + String aol) throws MojoFailureException { + // adjust aol + return aol == null ? new AOL(getArchitecture(architecture), getOS(os), + getLinkerName(architecture, os, linker)) : new AOL(aol); + } + + // FIXME, should go to AOL. + public static String getAOLKey(String architecture, String os, Linker linker) + throws MojoFailureException { + // construct AOL key prefix + return getArchitecture(architecture) + "." + getOS(os) + "." + + getLinkerName(architecture, os, linker) + "."; + } + + public static String getAOLKey(String aol) { + // FIXME, this may not always work correctly + return replace("-", ".", aol); + } + + public static File getJavaHome(File javaHome, String os) { + // adjust JavaHome + if (javaHome == null) { + javaHome = new File(System.getProperty("java.home")); + if (!getOS(os).equals("MacOSX")) { + javaHome = new File(javaHome, ".."); + } + } + return javaHome; + } + + public static void makeExecutable(File file, final Log log) + throws MojoExecutionException, MojoFailureException { + if (!file.exists()) + return; + + if (file.isDirectory()) { + File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + makeExecutable(files[i], log); + } + } + if (file.isFile() && file.canRead() && file.canWrite() + && !file.isHidden()) { + // chmod +x file + int result = runCommand("chmod", new String[] { "+x", + file.getPath() }, null, log); + if (result != 0) { + throw new MojoExecutionException("Failed to execute 'chmod +x " + + file.getPath() + "'" + " return code: \'" + result + + "\'."); + } + } + } + + public static void runRanlib(File file, final Log log) + throws MojoExecutionException, MojoFailureException { + if (!file.exists()) { + return; + } + + if (file.isDirectory()) { + File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + runRanlib(files[i], log); + } + } + if (file.isFile() && file.canRead() && file.canWrite() + && !file.isHidden() && file.getName().endsWith(".a")) { + // ranlib file + int result = runCommand("ranlib", new String[] { file.getPath() }, + null, log); + if (result != 0) { + throw new MojoExecutionException("Failed to execute 'ranlib " + + file.getPath() + "'" + " return code: \'" + result + + "\'."); + } + } + } + + /** + * Returns the Bcel Class corresponding to the given class filename + * + * @param filename + * the absolute file name of the class + * @return the Bcel Class. + * @throws IOException, + * ClassFormatException + */ + public static final JavaClass getBcelClass(String filename) + throws IOException, ClassFormatException { + ClassParser parser = new ClassParser(filename); + return parser.parse(); + } + + /** + * Returns the header file name (javah) corresponding to the given class + * file name + * + * @param filename + * the absolute file name of the class + * @return the header file name. + */ + public static final String getHeaderName(String base, String filename) { + base = base.replaceAll("\\\\", "/"); + filename = filename.replaceAll("\\\\", "/"); + if (!filename.startsWith(base)) { + throw new IllegalArgumentException("Error " + filename + + " does not start with " + base); + } + String header = filename.substring(base.length() + 1); + header = header.replaceAll("/", "_"); + header = header.replaceAll("\\.class", ".h"); + return header; + } + + /** + * Replaces target with replacement in string. For jdk 1.4 compatiblity. + * + * @param target + * @param replacement + * @param string + * @return + */ + public static String replace(CharSequence target, CharSequence replacement, + String string) { + return Pattern.compile(quote(target.toString())/* + * , Pattern.LITERAL jdk + * 1.4 + */).matcher(string).replaceAll( + /* Matcher. jdk 1.4 */quoteReplacement(replacement.toString())); + } + + /* for jdk 1.4 */ + private static String quote(String s) { + int slashEIndex = s.indexOf("\\E"); + if (slashEIndex == -1) + return "\\Q" + s + "\\E"; + + StringBuffer sb = new StringBuffer(s.length() * 2); + sb.append("\\Q"); + slashEIndex = 0; + int current = 0; + while ((slashEIndex = s.indexOf("\\E", current)) != -1) { + sb.append(s.substring(current, slashEIndex)); + current = slashEIndex + 2; + sb.append("\\E\\\\E\\Q"); + } + sb.append(s.substring(current, s.length())); + sb.append("\\E"); + return sb.toString(); + } + + /* for jdk 1.4 */ + private static String quoteReplacement(String s) { + if ((s.indexOf('\\') == -1) && (s.indexOf('$') == -1)) + return s; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '\\') { + sb.append('\\'); + sb.append('\\'); + } else if (c == '$') { + sb.append('\\'); + sb.append('$'); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + public static final String DEFAULT_EXCLUDES = "**/*~,**/#*#,**/.#*,**/%*%,**/._*," + + "**/CVS,**/CVS/**,**/.cvsignore," + + "**/SCCS,**/SCCS/**,**/vssver.scc," + + "**/.svn,**/.svn/**,**/.DS_Store"; + + public static int copyDirectoryStructure(File sourceDirectory, + File destinationDirectory, String includes, String excludes) + throws IOException { + if (!sourceDirectory.exists()) { + throw new IOException("Source directory doesn't exists (" + + sourceDirectory.getAbsolutePath() + ")."); + } + + List files = FileUtils.getFiles(sourceDirectory, includes, excludes); + String sourcePath = sourceDirectory.getAbsolutePath(); + + int copied = 0; + for (Iterator i = files.iterator(); i.hasNext();) { + File file = (File) i.next(); + String dest = file.getAbsolutePath(); + dest = dest.substring(sourcePath.length() + 1); + File destination = new File(destinationDirectory, dest); + if (file.isFile()) { + destination = destination.getParentFile(); + FileUtils.copyFileToDirectory(file, destination); + copied++; + } else if (file.isDirectory()) { + if (!destination.exists() && !destination.mkdirs()) { + throw new IOException( + "Could not create destination directory '" + + destination.getAbsolutePath() + "'."); + } + copied += copyDirectoryStructure(file, destination, includes, + excludes); + } else { + throw new IOException("Unknown file type: " + + file.getAbsolutePath()); + } + } + return copied; + } + + public static String getEnv(String envKey, String alternateSystemProperty, + String defaultValue) { + String envValue = null; + try { + envValue = System.getenv(envKey); + if (envValue == null && alternateSystemProperty != null) { + envValue = System.getProperty(alternateSystemProperty); + } + } catch (Error e) { + // JDK 1.4? + if (alternateSystemProperty != null) { + envValue = System.getProperty(alternateSystemProperty); + } + } + + if (envValue == null) { + envValue = defaultValue; + } + + return envValue; + } + + public static String addLibraryPathToEnv(String path, Map environment, + String os) { + String pathName = null; + char separator = ' '; + if (os.equals(OS.WINDOWS)) { + pathName = "PATH"; + separator = ';'; + } else if (os.equals(OS.MACOSX)) { + pathName = "DYLD_LIBRARY_PATH"; + separator = ':'; + } else { + pathName = "LD_LIBRARY_PATH"; + separator = ':'; + } + + String value = environment != null ? (String) environment.get(pathName) + : null; + if (value == null) { + value = NarUtil.getEnv(pathName, pathName, null); + } + + path = path.replace(File.pathSeparatorChar, separator); + if (value != null) { + value += separator + path; + } else { + value = path; + } + if (environment != null) { + environment.put(pathName, value); + } + return pathName + "=" + value; + } + + public static int runCommand(String cmd, String[] args, String[] env, + Log log) throws MojoExecutionException, MojoFailureException { + log.debug("RunCommand: " + cmd); + Commandline cmdLine = new Commandline(); + cmdLine.setExecutable(cmd); + if (args != null) { + for (int i = 0; i < args.length; i++) { + log.debug(" '" + args[i] + "'"); + } + cmdLine.addArguments(args); + } + + if (env != null) { + log.debug("with Env:"); + for (int i = 0; i < env.length; i++) { + String[] nameValue = env[i].split("=", 2); + if (nameValue.length < 2) + throw new MojoFailureException(" Misformed env: '" + + env[i] + "'"); + log.debug(" '" + env[i] + "'"); + cmdLine.addEnvironment(nameValue[0], nameValue[1]); + } + } + + try { + Process process = cmdLine.execute(); + StreamGobbler errorGobbler = new StreamGobbler(process + .getErrorStream(), true, log); + StreamGobbler outputGobbler = new StreamGobbler(process + .getInputStream(), false, log); + + errorGobbler.start(); + outputGobbler.start(); + process.waitFor(); + return process.exitValue(); + } catch (Throwable e) { + throw new MojoExecutionException("Could not launch " + cmdLine, e); + } + } + + static class StreamGobbler extends Thread { + InputStream is; + boolean error; + Log log; + + StreamGobbler(InputStream is, boolean error, Log log) { + this.is = is; + this.error = error; + this.log = log; + } + + public void run() { + try { + BufferedReader reader = new BufferedReader( + new InputStreamReader(is)); + String line = null; + while ((line = reader.readLine()) != null) { + if (error) { + log.error(line); + } else { + log.debug(line); + } + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/src/main/java/org/apache/maven/plugin/nar/OS.java b/src/main/java/org/apache/maven/plugin/nar/OS.java new file mode 100644 index 0000000..838f803 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/OS.java @@ -0,0 +1,15 @@ +// Copyright FreeHEP, 2007. +package org.freehep.maven.nar; + +/** + * + * @author Mark Donszelmann + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/OS.java bf894e19f5aa 2007/07/07 15:33:36 duns $ + */ +public interface OS { + + public final String MACOSX = "MacOSX"; + public final String WINDOWS = "Windows"; + public final String LINUX = "Linux"; + public final String SUNOS = "SunOS"; +} diff --git a/src/main/java/org/apache/maven/plugin/nar/SysLib.java b/src/main/java/org/apache/maven/plugin/nar/SysLib.java new file mode 100644 index 0000000..8204bae --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/SysLib.java @@ -0,0 +1,47 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; +import net.sf.antcontrib.cpptasks.types.SystemLibrarySet; + +import org.apache.maven.plugin.MojoFailureException; +import org.apache.tools.ant.Project; + +/** + * Keeps info on a system library + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/SysLib.java eda4d0bbde3d 2007/07/03 16:52:10 duns $ + */ +public class SysLib { + + /** + * Name of the system library + * + * @parameter expression="" + * @required + */ + private String name; + + /** + * Type of linking for this system library + * + * @parameter expression="" default-value="shared" + * @required + */ + private String type = Library.SHARED; + + public SystemLibrarySet getSysLibSet(Project antProject) throws MojoFailureException { + if (name == null) { + throw new MojoFailureException("NAR: Please specify <Name> as part of <SysLib>"); + } + SystemLibrarySet sysLibSet = new SystemLibrarySet(); + sysLibSet.setProject(antProject); + sysLibSet.setLibs(new CUtil.StringArrayBuilder(name)); + LibraryTypeEnum sysLibType = new LibraryTypeEnum(); + sysLibType.setValue(type); + sysLibSet.setType(sysLibType); + return sysLibSet; + } +} diff --git a/src/main/java/org/apache/maven/plugin/nar/Test.java b/src/main/java/org/apache/maven/plugin/nar/Test.java new file mode 100644 index 0000000..ac51491 --- /dev/null +++ b/src/main/java/org/apache/maven/plugin/nar/Test.java @@ -0,0 +1,68 @@ +// Copyright FreeHEP, 2005-2007. +package org.freehep.maven.nar; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.plugin.MojoFailureException; + +/** + * Sets up a test to create + * + * @author <a href="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</a> + * @version $Id: plugin/src/main/java/org/freehep/maven/nar/Test.java c867ab546be1 2007/07/05 21:26:30 duns $ + */ +public class Test implements Executable { + + /** + * Name of the test to create + * + * @required + * @parameter expression="" + */ + protected String name = null; + + /** + * Type of linking used for this test + * Possible choices are: "shared" or "static". + * Defaults to "shared". + * + * @parameter expression="" + */ + protected String link = Library.SHARED; + + /** + * When true run this test. + * Defaults to true; + * + * @parameter expresssion="" + */ + protected boolean run=true; + + /** + * Arguments to be used for running this test. + * Defaults to empty list. This option is + * only used if run=true. + * + * @parameter expression="" + */ + protected List/*<String>*/ args = new ArrayList(); + + public String getName() throws MojoFailureException { + if (name == null) throw new MojoFailureException("NAR: Please specify <Name> as part of <Test>"); + return name; + } + + public String getLink() { + return link; + } + + public boolean shouldRun() { + return run; + } + + public List/*<String>*/ getArgs() { + return args; + } +} + diff --git a/src/main/resources/META-INF/plexus/components.xml b/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000..a857d5d --- /dev/null +++ b/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,59 @@ +<component-set> + <components> + <component> + <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role> + <role-hint>nar</role-hint> + <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation> + <configuration> + <phases> + <generate-sources>org.freehep:freehep-nar-plugin:nar-download, + org.freehep:freehep-nar-plugin:nar-system-generate</generate-sources> + <process-sources>org.freehep:freehep-nar-plugin:nar-unpack</process-sources> + <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources, + org.freehep:freehep-nar-plugin:nar-resources</process-resources> + <compile>org.apache.maven.plugins:maven-compiler-plugin:compile, + org.freehep:freehep-nar-plugin:nar-javah</compile> + <process-classes>org.freehep:freehep-nar-plugin:nar-compile</process-classes> + <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources> + <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile, + org.freehep:freehep-nar-plugin:nar-testCompile</test-compile> + <test>org.apache.maven.plugins:maven-surefire-plugin:test, + org.freehep:freehep-nar-plugin:nar-test</test> + <package>org.freehep:freehep-nar-plugin:nar-package, + org.apache.maven.plugins:maven-jar-plugin:jar</package> + <integration-test>org.freehep:freehep-nar-plugin:nar-integration-test</integration-test> + <install>org.apache.maven.plugins:maven-install-plugin:install</install> + <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy> + </phases> + </configuration> + </component> + + <component> + <role>org.apache.maven.artifact.handler.ArtifactHandler</role> + <role-hint>nar-artifact</role-hint> + <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation> + <configuration> + <type>nar-artifact</type> + <extension>jar</extension> + <packaging>nar</packaging> + <language>java</language> + <addedToClasspath>true</addedToClasspath> + <classifier/> + </configuration> + </component> + + <component> + <role>org.codehaus.plexus.archiver.Archiver</role> + <role-hint>nar-library</role-hint> + <implementation>org.freehep.maven.nar.NarArchiver</implementation> + <instantiation-strategy>per-lookup</instantiation-strategy> + </component> + + <component> + <role>org.codehaus.plexus.archiver.UnArchiver</role> + <role-hint>nar-library</role-hint> + <implementation>org.freehep.maven.nar.NarUnArchiver</implementation> + <instantiation-strategy>per-lookup</instantiation-strategy> + </component> + </components> +</component-set> diff --git a/src/main/resources/org/apache/maven/plugin/nar/aol.properties b/src/main/resources/org/apache/maven/plugin/nar/aol.properties new file mode 100644 index 0000000..11a9e61 --- /dev/null +++ b/src/main/resources/org/apache/maven/plugin/nar/aol.properties @@ -0,0 +1,425 @@ +# +# AOL (Architecture-OperatingSystem-Linker) Default Values +# +# @author Mark Donszelmann +# @version $Id$ +# + +# +# Windows ("Windows *" => Windows) +# +x86.Windows.linker=msvc + +x86.Windows.msvc.cpp.compiler=msvc +x86.Windows.msvc.cpp.defines=Windows WIN32 +x86.Windows.msvc.cpp.options= +x86.Windows.msvc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +x86.Windows.msvc.cpp.excludes= + +x86.Windows.msvc.c.compiler=msvc +x86.Windows.msvc.c.defines=Windows WIN32 +x86.Windows.msvc.c.options= +x86.Windows.msvc.c.includes=**/*.c +x86.Windows.msvc.c.excludes= + +x86.Windows.msvc.fortran.compiler=df +x86.Windows.msvc.fortran.defines=Windows WIN32 +x86.Windows.msvc.fortran.options= +x86.Windows.msvc.fortran.includes=**/*.f **/*.for +x86.Windows.msvc.fortran.excludes= + +x86.Windows.msvc.java.include=include;include/win32 +x86.Windows.msvc.java.runtimeDirectory=lib + +x86.Windows.msvc.lib.prefix= +x86.Windows.msvc.shared.prefix= +x86.Windows.msvc.shared.extension=dll +x86.Windows.msvc.static.extension=lib +x86.Windows.msvc.plugin.extension=dll +x86.Windows.msvc.jni.extension=dll +x86.Windows.msvc.executable.extension=exe + +#x86.Windows.msvc.arch.includes=lib/**/*.lib lib/**/*.dll + +# +# Windows g++ +# +x86.Windows.g++.cpp.compiler=g++ +x86.Windows.g++.cpp.defines=Windows +x86.Windows.g++.cpp.options=-Wall +x86.Windows.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +x86.Windows.g++.cpp.excludes= + +x86.Windows.g++.c.compiler=gcc +x86.Windows.g++.c.defines=Windows +x86.Windows.g++.c.options=-Wall +x86.Windows.g++.c.includes=**/*.c +x86.Windows.g++.c.excludes= + +x86.Windows.g++.fortran.compiler=g77 +x86.Windows.g++.fortran.defines=Windows +x86.Windows.g++.fortran.options=-Wall +x86.Windows.g++.fortran.includes=**/*.f **/*.for +x86.Windows.g++.fortran.excludes= + +x86.Windows.g++.java.include=include;include/win32 +x86.Windows.g++.java.runtimeDirectory=lib + +x86.Windows.g++.lib.prefix=lib +x86.Windows.g++.shared.prefix= +x86.Windows.g++.static.extension=a +x86.Windows.g++.shared.extension=dll +x86.Windows.g++.plugin.extension=dll +x86.Windows.g++.jni.extension=dll +x86.Windows.g++.executable.extension= + +# FIXME to be removed when NARPLUGIN-137 +x86.Windows.gcc.static.extension=a +x86.Windows.gcc.shared.extension=dll +x86.Windows.gcc.plugin.extension=dll +x86.Windows.gcc.jni.extension=dll + +# +# Linux +# +i386.Linux.linker=g++ + +i386.Linux.g++.cpp.compiler=g++ +i386.Linux.g++.cpp.defines=Linux GNU_GCC f2cFortran +i386.Linux.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.Linux.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.g++.cpp.excludes= + +i386.Linux.g++.c.compiler=gcc +i386.Linux.g++.c.defines=Linux GNU_GCC f2cFortran +i386.Linux.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.Linux.g++.c.includes=**/*.c +i386.Linux.g++.c.excludes= + +i386.Linux.g++.fortran.compiler=g77 +i386.Linux.g++.fortran.defines=Linux GNU_GCC f2cFortran +i386.Linux.g++.fortran.options=-Wall +i386.Linux.g++.fortran.includes=**/*.f **/*.for +i386.Linux.g++.fortran.excludes= + +i386.Linux.g++.java.include=include;include/linux +i386.Linux.g++.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.g++.lib.prefix=lib +i386.Linux.g++.shared.prefix=lib +i386.Linux.g++.static.extension=a +i386.Linux.g++.shared.extension=so +i386.Linux.g++.plugin.extension=so +i386.Linux.g++.jni.extension=so +i386.Linux.g++.executable.extension= + +# FIXME to be removed when NARPLUGIN-137 +i386.Linux.gcc.static.extension=a +i386.Linux.gcc.shared.extension=so +i386.Linux.gcc.plugin.extension=so +i386.Linux.gcc.jni.extension=so + +#i386.Linux.g++.arch.includes=lib/**/*.a lib/**/*.so + +# +# Linux icc (C linker) +# +i386.Linux.icc.cpp.compiler=NONE +i386.Linux.icc.cpp.defines=Linux +i386.Linux.icc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.icc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.icc.cpp.excludes= + +i386.Linux.icc.c.compiler=icc +i386.Linux.icc.c.defines=Linux +i386.Linux.icc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.icc.c.includes=**/*.c +i386.Linux.icc.c.excludes= + +i386.Linux.icc.fortran.compiler=ifort +i386.Linux.icc.fortran.defines=Linux +i386.Linux.icc.fortran.options= +i386.Linux.icc.fortran.includes=**/*.f **/*.for +i386.Linux.icc.fortran.excludes= + +i386.Linux.icc.java.include=include;include/linux +i386.Linux.icc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.icc.lib.prefix=lib +i386.Linux.icc.shared.prefix=lib +i386.Linux.icc.static.extension=a +i386.Linux.icc.shared.extension=so +i386.Linux.icc.plugin.extension=so +i386.Linux.icc.jni.extension=so +i386.Linux.icc.executable.extension= + + +# +# Linux icpc (C++ linker) +# +i386.Linux.icpc.cpp.compiler=icpc +i386.Linux.icpc.cpp.defines=Linux +i386.Linux.icpc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.icpc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.icpc.cpp.excludes= + +i386.Linux.icpc.c.compiler=icc +i386.Linux.icpc.c.defines=Linux +i386.Linux.icpc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.icpc.c.includes=**/*.c +i386.Linux.icpc.c.excludes= + +i386.Linux.icpc.fortran.compiler=ifort +i386.Linux.icpc.fortran.defines=Linux +i386.Linux.icpc.fortran.options= +i386.Linux.icpc.fortran.includes=**/*.f **/*.for +i386.Linux.icpc.fortran.excludes= + +i386.Linux.icpc.java.include=include;include/linux +i386.Linux.icpc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.icpc.lib.prefix=lib +i386.Linux.icpc.shared.prefix=lib +i386.Linux.icpc.static.extension=a +i386.Linux.icpc.shared.extension=so +i386.Linux.icpc.plugin.extension=so +i386.Linux.icpc.jni.extension=so +i386.Linux.icpc.executable.extension= + +# +# Linux ecc (C linker) +# +i386.Linux.ecc.cpp.compiler=NONE +i386.Linux.ecc.cpp.defines=Linux +i386.Linux.ecc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.ecc.cpp.excludes= + +i386.Linux.ecc.c.compiler=ecc +i386.Linux.ecc.c.defines=Linux +i386.Linux.ecc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecc.c.includes=**/*.c +i386.Linux.ecc.c.excludes= + +# Should this be efc ? +i386.Linux.ecc.fortran.compiler=ifort +i386.Linux.ecc.fortran.defines=Linux +i386.Linux.ecc.fortran.options= +i386.Linux.ecc.fortran.includes=**/*.f **/*.for +i386.Linux.ecc.fortran.excludes= + +i386.Linux.ecc.java.include=include;include/linux +i386.Linux.ecc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.ecc.lib.prefix=lib +i386.Linux.ecc.shared.prefix=lib +i386.Linux.ecc.static.extension=a +i386.Linux.ecc.shared.extension=so +i386.Linux.ecc.plugin.extension=so +i386.Linux.ecc.jni.extension=so +i386.Linux.ecc.executable.extension= + +# +# Linux ecpc (C++ linker) +# +i386.Linux.ecpc.cpp.compiler=ecpc +i386.Linux.icpc.cpp.defines=Linux +i386.Linux.ecpc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecpc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.ecpc.cpp.excludes= + +i386.Linux.ecpc.c.compiler=ecc +i386.Linux.ecpc.c.defines=Linux +i386.Linux.ecpc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecpc.c.includes=**/*.c +i386.Linux.ecpc.c.excludes= + +# Should this be efc ? +i386.Linux.ecpc.fortran.compiler=ifort +i386.Linux.ecpc.fortran.defines=Linux +i386.Linux.ecpc.fortran.options= +i386.Linux.ecpc.fortran.includes=**/*.f **/*.for +i386.Linux.ecpc.fortran.excludes= + +i386.Linux.ecpc.java.include=include;include/linux +i386.Linux.ecpc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.ecpc.lib.prefix=lib +i386.Linux.ecpc.shared.prefix=lib +i386.Linux.ecpc.static.extension=a +i386.Linux.ecpc.shared.extension=so +i386.Linux.ecpc.plugin.extension=so +i386.Linux.ecpc.jni.extension=so +i386.Linux.ecpc.executable.extension= + +# +# Linux +# +amd64.Linux.linker=g++ + +amd64.Linux.g++.cpp.compiler=g++ +amd64.Linux.g++.cpp.defines=Linux GNU_GCC f2cFortran +amd64.Linux.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +amd64.Linux.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +amd64.Linux.g++.cpp.excludes= + +amd64.Linux.g++.c.compiler=gcc +amd64.Linux.g++.c.defines=Linux GNU_GCC f2cFortran +amd64.Linux.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +amd64.Linux.g++.c.includes=**/*.c +amd64.Linux.g++.c.excludes= + +amd64.Linux.g++.fortran.compiler=g77 +amd64.Linux.g++.fortran.defines=Linux GNU_GCC f2cFortran +amd64.Linux.g++.fortran.options=-Wall +amd64.Linux.g++.fortran.includes=**/*.f **/*.for +amd64.Linux.g++.fortran.excludes= + +amd64.Linux.g++.java.include=include;include/linux +amd64.Linux.g++.java.runtimeDirectory=jre/lib/amd64/server + +amd64.Linux.g++.lib.prefix=lib +amd64.Linux.g++.shared.prefix=lib +amd64.Linux.g++.static.extension=a +amd64.Linux.g++.shared.extension=so +amd64.Linux.g++.plugin.extension=so +amd64.Linux.g++.jni.extension=so +amd64.Linux.g++.executable.extension= + +# FIXME to be removed when NARPLUGIN-137 +amd64.Linux.gcc.static.extension=a +amd64.Linux.gcc.shared.extension=so +amd64.Linux.gcc.plugin.extension=so +amd64.Linux.gcc.jni.extension=so + +#amd64.Linux.g++.arch.includes=lib/**/*.a lib/**/*.so + +# +# MacOSX ("Mac OS X" => MacOSX) PowerPC +# +ppc.MacOSX.linker=g++ + +ppc.MacOSX.g++.cpp.compiler=g++ +ppc.MacOSX.g++.cpp.defines=Darwin GNU_GCC f2cFortran +ppc.MacOSX.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +ppc.MacOSX.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +ppc.MacOSX.g++.cpp.excludes= + +ppc.MacOSX.g++.c.compiler=gcc +ppc.MacOSX.g++.c.defines=Darwin GNU_GCC f2cFortran +ppc.MacOSX.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +ppc.MacOSX.g++.c.includes=**/*.c +ppc.MacOSX.g++.c.excludes= + +ppc.MacOSX.g++.fortran.compiler=g77 +ppc.MacOSX.g++.fortran.defines=Darwin GNU_GCC +ppc.MacOSX.g++.fortran.options=-Wall -fno-automatic -fno-second-underscore +ppc.MacOSX.g++.fortran.includes=**/*.f **/*.for +ppc.MacOSX.g++.fortran.excludes= + +ppc.MacOSX.g++.java.include=include +ppc.MacOSX.g++.java.runtimeDirectory=IGNORED + +ppc.MacOSX.g++.lib.prefix=lib +ppc.MacOSX.g++.shared.prefix=lib +ppc.MacOSX.g++.static.extension=a +ppc.MacOSX.g++.shared.extension=dylib +ppc.MacOSX.g++.plugin.extension=bundle +ppc.MacOSX.g++.jni.extension=jnilib +ppc.MacOSX.g++.executable.extension= + +# FIXME to be removed when NARPLUGIN-137 +ppc.MacOSX.gcc.static.extension=a +ppc.MacOSX.gcc.shared.extension=dylib +ppc.MacOSX.gcc.plugin.extension=bundle +ppc.MacOSX.gcc.jni.extension=jnilib + +#ppc.MacOSX.g++.arch.includes=lib/**/*.a lib/**/*.so lib/**/*.dylib lib/**/*.jnilib + +# +# MacOSX ("Mac OS X" => MacOSX) Intel +# +i386.MacOSX.linker=g++ + +i386.MacOSX.g++.cpp.compiler=g++ +i386.MacOSX.g++.cpp.defines=Darwin GNU_GCC +i386.MacOSX.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.MacOSX.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.MacOSX.g++.cpp.excludes= + +i386.MacOSX.g++.c.compiler=gcc +i386.MacOSX.g++.c.defines=Darwin GNU_GCC +i386.MacOSX.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.MacOSX.g++.c.includes=**/*.c +i386.MacOSX.g++.c.excludes= + +i386.MacOSX.g++.fortran.compiler=gfortran +i386.MacOSX.g++.fortran.defines=Darwin GNU_GCC +i386.MacOSX.g++.fortran.options=-Wall -fno-automatic -fno-second-underscore +i386.MacOSX.g++.fortran.includes=**/*.f **/*.for +i386.MacOSX.g++.fortran.excludes= + +i386.MacOSX.g++.java.include=include +i386.MacOSX.g++.java.runtimeDirectory=IGNORED + +i386.MacOSX.g++.lib.prefix=lib +i386.MacOSX.g++.shared.prefix=lib +i386.MacOSX.g++.static.extension=a +i386.MacOSX.g++.shared.extension=dylib +i386.MacOSX.g++.plugin.extension=bundle +i386.MacOSX.g++.jni.extension=jnilib +i386.MacOSX.g++.executable.extension= + +# FIXME to be removed when NARPLUGIN-137 +i386.MacOSX.gcc.static.extension=a +i386.MacOSX.gcc.shared.extension=dylib +i386.MacOSX.gcc.plugin.extension=bundle +i386.MacOSX.gcc.jni.extension=jnilib + +#i386.MacOSX.g++.arch.includes=lib/**/*.a lib/**/*.so lib/**/*.dylib lib/**/*.jnilib + +# +# Solaris +# +sparc.SunOS.linker=CC + +sparc.SunOS.CC.cpp.compiler=CC +sparc.SunOS.CC.cpp.defines=SOLARIS2 +sparc.SunOS.CC.cpp.options= +sparc.SunOS.CC.cpp.includes=**/*.cc **/*.cpp **/*.cxx +sparc.SunOS.CC.cpp.excludes= + +sparc.SunOS.CC.c.compiler=suncc +sparc.SunOS.CC.c.defines=SOLARIS2 +sparc.SunOS.CC.c.options= +sparc.SunOS.CC.c.includes=**/*.c +sparc.SunOS.CC.c.excludes= + +sparc.SunOS.CC.fortran.compiler=sunf77 +sparc.SunOS.CC.fortran.defines=SOLARIS2 +sparc.SunOS.CC.fortran.options= +sparc.SunOS.CC.fortran.includes=**/*.f **/*.for +sparc.SunOS.CC.fortran.excludes= + +sparc.SunOS.CC.java.include=include;include/solaris +sparc.SunOS.CC.java.runtimeDirectory=jre/lib/sparc/server + +sparc.SunOS.CC.linker.systemLibs=pthread:shared + +sparc.SunOS.CC.lib.prefix=lib +sparc.SunOS.CC.shared.prefix=lib +sparc.SunOS.CC.static.extension=a +sparc.SunOS.CC.shared.extension=so +sparc.SunOS.CC.plugin.extension=so +sparc.SunOS.CC.jni.extension=so +sparc.SunOS.CC.executable.extension= + +# FIXME to be removed when NARPLUGIN-137 +sparc.SunOS.cc.static.extension=a +sparc.SunOS.cc.shared.extension=so +sparc.SunOS.cc.plugin.extension=so +sparc.SunOS.cc.jni.extension=so + +#sparc.SunOS.CC.arch.includes=lib/**/*.a lib/**/*.so + + diff --git a/src/site/apt/HelloWorld.apt b/src/site/apt/HelloWorld.apt new file mode 100644 index 0000000..90f5123 --- /dev/null +++ b/src/site/apt/HelloWorld.apt @@ -0,0 +1,61 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +HelloWorld Examples + + These example contain a simple C method "sayHello". This method can be called from a C program, a Java program, put into +a static library, put into a shared library, use a third party library, ... +There are also some unit test which are run and call the same method. + + The following examples are available: + + [helloworldexe] A C routine. + + [helloworldstaticexe] A C routine statically linked with the C-runtime library. + + [] + + [helloworldjni] A C routine called from Java and a Java unit test. + + [helloworldjnilibjava] A java project which depends on helloworldjni. + + [helloworldstaticjni] A C routine called from Java statically linked with the C-runtime library and a Java unit test. + + [hellothirdpartyjni] A third party JNI library called from Java. + The third party library is "helloworldjni" and is added as resource to the project in the + form of a JNI library and a corresponding jar file. A Java unit test is provided. + + [] + + [helloworldsharedlib] A C routine which gets archived into a shared library. A C test executable + is created and run. + + [helloworldsharedlibexe] A C executable which depends on "helloworldsharedlib" and links dynamically + with it. The executable is created and run. + + [helloworldsharedlibjni] A C routine called from Java, which depends on + "helloworldsharedlib" and links dynamically with it. A Java unit test is provided. + + [] + + [helloworldstaticlib] A C routine which gets archived into a static library. A C test executable + is created and run. + + [helloworldstaticlibexe] A C executable which depends on "helloworldstaticlib" and links statically + with it. The executabe is created and run. + + [helloworldstaticlibjni] A C routine called from Java, which depends on + "helloworldstaticlib" and links statically with it. A Java unit test is provided. + + [] + + These examples are now all run as tests when you try to run maven on the freehep-nar-plugin from its top-level directory. + + For the sources of these tests, see: +{{{http://java.freehep.org/svn/repobrowser.svn?path=%2ffreehep%2ftrunk%2fmaven-plugins%2ffreehep-nar-plugin%2ftests&revision=HEAD&name=freehep&bypassEmpty=true} +the SVN repository}}. + diff --git a/src/site/apt/aol.apt b/src/site/apt/aol.apt new file mode 100644 index 0000000..0acaa96 --- /dev/null +++ b/src/site/apt/aol.apt @@ -0,0 +1,384 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +AOL Properties + + Below a copy of the AOL Properties file which is used by the NAR plugin for AOL dependent default settings: + ++-- +# +# Windows ("Windows *" => Windows) +# +x86.Windows.linker=msvc + +x86.Windows.msvc.cpp.compiler=msvc +x86.Windows.msvc.cpp.defines=Windows WIN32 +x86.Windows.msvc.cpp.options= +x86.Windows.msvc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +x86.Windows.msvc.cpp.excludes= + +x86.Windows.msvc.c.compiler=msvc +x86.Windows.msvc.c.defines=Windows WIN32 +x86.Windows.msvc.c.options= +x86.Windows.msvc.c.includes=**/*.c +x86.Windows.msvc.c.excludes= + +x86.Windows.msvc.fortran.compiler=df +x86.Windows.msvc.fortran.defines=Windows WIN32 +x86.Windows.msvc.fortran.options= +x86.Windows.msvc.fortran.includes=**/*.f **/*.for +x86.Windows.msvc.fortran.excludes= + +x86.Windows.msvc.java.include=include;include/win32 +x86.Windows.msvc.java.runtimeDirectory=lib + +x86.Windows.msvc.lib.prefix= +x86.Windows.msvc.shared.extension=dll +x86.Windows.msvc.static.extension=lib +x86.Windows.msvc.plugin.extension=dll +x86.Windows.msvc.jni.extension=dll +x86.Windows.msvc.executable.extension=exe + +#x86.Windows.msvc.arch.includes=lib/**/*.lib lib/**/*.dll + +# +# Windows g++ +# +x86.Windows.g++.cpp.compiler=g++ +x86.Windows.g++.cpp.defines=Windows +x86.Windows.g++.cpp.options=-Wall +x86.Windows.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +x86.Windows.g++.cpp.excludes= + +x86.Windows.g++.c.compiler=gcc +x86.Windows.g++.c.defines=Windows +x86.Windows.g++.c.options=-Wall +x86.Windows.g++.c.includes=**/*.c +x86.Windows.g++.c.excludes= + +x86.Windows.g++.fortran.compiler=g77 +x86.Windows.g++.fortran.defines=Windows +x86.Windows.g++.fortran.options=-Wall +x86.Windows.g++.fortran.includes=**/*.f **/*.for +x86.Windows.g++.fortran.excludes= + +x86.Windows.g++.java.include=include;include/Windows +x86.Windows.g++.java.runtimeDirectory=lib + +x86.Windows.g++.lib.prefix=lib +x86.Windows.g++.static.extension=a +x86.Windows.g++.shared.extension=so +x86.Windows.g++.plugin.extension=so +x86.Windows.g++.jni.extension=so +x86.Windows.g++.executable.extension= + +# +# Linux +# +i386.Linux.linker=g++ + +i386.Linux.g++.cpp.compiler=g++ +i386.Linux.g++.cpp.defines=Linux GNU_GCC f2cFortran +i386.Linux.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.Linux.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.g++.cpp.excludes= + +i386.Linux.g++.c.compiler=gcc +i386.Linux.g++.c.defines=Linux GNU_GCC f2cFortran +i386.Linux.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.Linux.g++.c.includes=**/*.c +i386.Linux.g++.c.excludes= + +i386.Linux.g++.fortran.compiler=g77 +i386.Linux.g++.fortran.defines=Linux GNU_GCC f2cFortran +i386.Linux.g++.fortran.options=-Wall +i386.Linux.g++.fortran.includes=**/*.f **/*.for +i386.Linux.g++.fortran.excludes= + +i386.Linux.g++.java.include=include;include/linux +i386.Linux.g++.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.g++.lib.prefix=lib +i386.Linux.g++.static.extension=a +i386.Linux.g++.shared.extension=so +i386.Linux.g++.plugin.extension=so +i386.Linux.g++.jni.extension=so +i386.Linux.g++.executable.extension= + +#i386.Linux.g++.arch.includes=lib/**/*.a lib/**/*.so + +# +# Linux icc (C linker) +# +i386.Linux.icc.cpp.compiler=NONE +i386.Linux.icc.cpp.defines=Linux +i386.Linux.icc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.icc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.icc.cpp.excludes= + +i386.Linux.icc.c.compiler=icc +i386.Linux.icc.c.defines=Linux +i386.Linux.icc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.icc.c.includes=**/*.c +i386.Linux.icc.c.excludes= + +i386.Linux.icc.fortran.compiler=ifort +i386.Linux.icc.fortran.defines=Linux +i386.Linux.icc.fortran.options= +i386.Linux.icc.fortran.includes=**/*.f **/*.for +i386.Linux.icc.fortran.excludes= + +i386.Linux.icc.java.include=include;include/linux +i386.Linux.icc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.icc.lib.prefix=lib +i386.Linux.icc.static.extension=a +i386.Linux.icc.shared.extension=so +i386.Linux.icc.plugin.extension=so +i386.Linux.icc.jni.extension=so +i386.Linux.icc.executable.extension= + + +# +# Linux icpc (C++ linker) +# +i386.Linux.icpc.cpp.compiler=icpc +i386.Linux.icpc.cpp.defines=Linux +i386.Linux.icpc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.icpc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.icpc.cpp.excludes= + +i386.Linux.icpc.c.compiler=icc +i386.Linux.icpc.c.defines=Linux +i386.Linux.icpc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.icpc.c.includes=**/*.c +i386.Linux.icpc.c.excludes= + +i386.Linux.icpc.fortran.compiler=ifort +i386.Linux.icpc.fortran.defines=Linux +i386.Linux.icpc.fortran.options= +i386.Linux.icpc.fortran.includes=**/*.f **/*.for +i386.Linux.icpc.fortran.excludes= + +i386.Linux.icpc.java.include=include;include/linux +i386.Linux.icpc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.icpc.lib.prefix=lib +i386.Linux.icpc.static.extension=a +i386.Linux.icpc.shared.extension=so +i386.Linux.icpc.plugin.extension=so +i386.Linux.icpc.jni.extension=so +i386.Linux.icpc.executable.extension= + +# +# Linux ecc (C linker) +# +i386.Linux.ecc.cpp.compiler=NONE +i386.Linux.ecc.cpp.defines=Linux +i386.Linux.ecc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.ecc.cpp.excludes= + +i386.Linux.ecc.c.compiler=ecc +i386.Linux.ecc.c.defines=Linux +i386.Linux.ecc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecc.c.includes=**/*.c +i386.Linux.ecc.c.excludes= + +# Should this be efc ? +i386.Linux.ecc.fortran.compiler=ifort +i386.Linux.ecc.fortran.defines=Linux +i386.Linux.ecc.fortran.options= +i386.Linux.ecc.fortran.includes=**/*.f **/*.for +i386.Linux.ecc.fortran.excludes= + +i386.Linux.ecc.java.include=include;include/linux +i386.Linux.ecc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.ecc.lib.prefix=lib +i386.Linux.ecc.static.extension=a +i386.Linux.ecc.shared.extension=so +i386.Linux.ecc.plugin.extension=so +i386.Linux.ecc.jni.extension=so +i386.Linux.ecc.executable.extension= + +# +# Linux ecpc (C++ linker) +# +i386.Linux.ecpc.cpp.compiler=ecpc +i386.Linux.icpc.cpp.defines=Linux +i386.Linux.ecpc.cpp.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecpc.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.Linux.ecpc.cpp.excludes= + +i386.Linux.ecpc.c.compiler=ecc +i386.Linux.ecpc.c.defines=Linux +i386.Linux.ecpc.c.options=-ansi -mp -no-gcc -w1 +i386.Linux.ecpc.c.includes=**/*.c +i386.Linux.ecpc.c.excludes= + +# Should this be efc ? +i386.Linux.ecpc.fortran.compiler=ifort +i386.Linux.ecpc.fortran.defines=Linux +i386.Linux.ecpc.fortran.options= +i386.Linux.ecpc.fortran.includes=**/*.f **/*.for +i386.Linux.ecpc.fortran.excludes= + +i386.Linux.ecpc.java.include=include;include/linux +i386.Linux.ecpc.java.runtimeDirectory=jre/lib/i386/client + +i386.Linux.ecpc.lib.prefix=lib +i386.Linux.ecpc.static.extension=a +i386.Linux.ecpc.shared.extension=so +i386.Linux.ecpc.plugin.extension=so +i386.Linux.ecpc.jni.extension=so +i386.Linux.ecpc.executable.extension= + +# +# Linux +# +amd64.Linux.linker=g++ + +amd64.Linux.g++.cpp.compiler=g++ +amd64.Linux.g++.cpp.defines=Linux GNU_GCC f2cFortran +amd64.Linux.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +amd64.Linux.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +amd64.Linux.g++.cpp.excludes= + +amd64.Linux.g++.c.compiler=gcc +amd64.Linux.g++.c.defines=Linux GNU_GCC f2cFortran +amd64.Linux.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +amd64.Linux.g++.c.includes=**/*.c +amd64.Linux.g++.c.excludes= + +amd64.Linux.g++.fortran.compiler=g77 +amd64.Linux.g++.fortran.defines=Linux GNU_GCC f2cFortran +amd64.Linux.g++.fortran.options=-Wall +amd64.Linux.g++.fortran.includes=**/*.f **/*.for +amd64.Linux.g++.fortran.excludes= + +amd64.Linux.g++.java.include=include;include/linux +amd64.Linux.g++.java.runtimeDirectory=jre/lib/amd64/server + +amd64.Linux.g++.lib.prefix=lib +amd64.Linux.g++.static.extension=a +amd64.Linux.g++.shared.extension=so +amd64.Linux.g++.plugin.extension=so +amd64.Linux.g++.jni.extension=so +amd64.Linux.g++.executable.extension= + +#amd64.Linux.g++.arch.includes=lib/**/*.a lib/**/*.so + +# +# MacOSX ("Mac OS X" => MacOSX) +# +ppc.MacOSX.linker=g++ + +ppc.MacOSX.g++.cpp.compiler=g++ +ppc.MacOSX.g++.cpp.defines=Darwin GNU_GCC f2cFortran +ppc.MacOSX.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +ppc.MacOSX.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +ppc.MacOSX.g++.cpp.excludes= + +ppc.MacOSX.g++.c.compiler=gcc +ppc.MacOSX.g++.c.defines=Darwin GNU_GCC f2cFortran +ppc.MacOSX.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +ppc.MacOSX.g++.c.includes=**/*.c +ppc.MacOSX.g++.c.excludes= + +ppc.MacOSX.g++.fortran.compiler=g77 +ppc.MacOSX.g++.fortran.defines=Darwin GNU_GCC +ppc.MacOSX.g++.fortran.options=-Wall -fno-automatic -fno-second-underscore +ppc.MacOSX.g++.fortran.includes=**/*.f **/*.for +ppc.MacOSX.g++.fortran.excludes= + +ppc.MacOSX.g++.java.include=include +ppc.MacOSX.g++.java.runtimeDirectory=IGNORED + +ppc.MacOSX.g++.lib.prefix=lib +ppc.MacOSX.g++.static.extension=a +ppc.MacOSX.g++.shared.extension=dylib +ppc.MacOSX.g++.plugin.extension=bundle +ppc.MacOSX.g++.jni.extension=jnilib +ppc.MacOSX.g++.executable.extension= + +#ppc.MacOSX.g++.arch.includes=lib/**/*.a lib/**/*.so lib/**/*.dylib lib/**/*.jnilib + +# +# MacOSX ("Mac OS X" => MacOSX) Intel +# +i386.MacOSX.linker=g++ + +i386.MacOSX.g++.cpp.compiler=g++ +i386.MacOSX.g++.cpp.defines=Darwin GNU_GCC +i386.MacOSX.g++.cpp.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.MacOSX.g++.cpp.includes=**/*.cc **/*.cpp **/*.cxx +i386.MacOSX.g++.cpp.excludes= + +i386.MacOSX.g++.c.compiler=gcc +i386.MacOSX.g++.c.defines=Darwin GNU_GCC +i386.MacOSX.g++.c.options=-Wall -Wno-long-long -Wpointer-arith -Wconversion +i386.MacOSX.g++.c.includes=**/*.c +i386.MacOSX.g++.c.excludes= + +i386.MacOSX.g++.fortran.compiler=gfortran +i386.MacOSX.g++.fortran.defines=Darwin GNU_GCC +i386.MacOSX.g++.fortran.options=-Wall -fno-automatic -fno-second-underscore +i386.MacOSX.g++.fortran.includes=**/*.f **/*.for +i386.MacOSX.g++.fortran.excludes= + +i386.MacOSX.g++.java.include=include +i386.MacOSX.g++.java.runtimeDirectory=IGNORED + +i386.MacOSX.g++.lib.prefix=lib +i386.MacOSX.g++.static.extension=a +i386.MacOSX.g++.shared.extension=dylib +i386.MacOSX.g++.plugin.extension=bundle +i386.MacOSX.g++.jni.extension=jnilib +i386.MacOSX.g++.executable.extension= + +#i386.MacOSX.g++.arch.includes=lib/**/*.a lib/**/*.so lib/**/*.dylib lib/**/*.jnilib + +# +# Solaris +# +sparc.SunOS.linker=CC + +sparc.SunOS.CC.cpp.compiler=CC +sparc.SunOS.CC.cpp.defines=SOLARIS2 +sparc.SunOS.CC.cpp.options= +sparc.SunOS.CC.cpp.includes=**/*.cc **/*.cpp **/*.cxx +sparc.SunOS.CC.cpp.excludes= + +sparc.SunOS.CC.c.compiler=suncc +sparc.SunOS.CC.c.defines=SOLARIS2 +sparc.SunOS.CC.c.options= +sparc.SunOS.CC.c.includes=**/*.c +sparc.SunOS.CC.c.excludes= + +sparc.SunOS.CC.fortran.compiler=sunf77 +sparc.SunOS.CC.fortran.defines=SOLARIS2 +sparc.SunOS.CC.fortran.options= +sparc.SunOS.CC.fortran.includes=**/*.f **/*.for +sparc.SunOS.CC.fortran.excludes= + +sparc.SunOS.CC.java.include=include;include/solaris +sparc.SunOS.CC.java.runtimeDirectory=jre/lib/sparc/server + +sparc.SunOS.CC.linker.systemLibs=pthread:shared + +sparc.SunOS.CC.lib.prefix=lib +sparc.SunOS.CC.static.extension=a +sparc.SunOS.CC.shared.extension=so +sparc.SunOS.CC.plugin.extension=so +sparc.SunOS.CC.jni.extension=so +sparc.SunOS.CC.executable.extension= + +#sparc.SunOS.CC.arch.includes=lib/**/*.a lib/**/*.so ++-- + + diff --git a/src/site/apt/configuration.apt b/src/site/apt/configuration.apt new file mode 100644 index 0000000..6b01b91 --- /dev/null +++ b/src/site/apt/configuration.apt @@ -0,0 +1,453 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +NAR Configuration + + The following shows the possible tags in the NAR configuration section: + ++-- +<configuration> + <arch/> + <os/> + <javaHome/> + <aol/> + <resourceDirectory/> + <resourceBinDir/> + <resourceIncludeDir/> + <resourceLibDir/> + <maxCores/> + <targetDirectory/> + <output/> + <failOnError/> + <runtime/> + <libtool/> + + <libraries> + <library> + <type/> + <linkCPP/> + <linkFortran/> + <run/> + <args> + <arg/> + </args> + </library> + </libraries> + + <tests> + <test> + <name/> + <link/> + <run/> + <args> + <arg/> + </args> + </test> + </tests> + + <linker> + <name/> + <incremental/> + <map/> + <options> + <option/> + </options> + <clearDefaultOptions/> + <libs> + <lib> + <name/> + <type/> + <directory/> + </lib> + </libs> + <sysLibs> + <sysLib> + <name/> + <type/> + </sysLib> + </sysLibs> + </linker> + + <cpp> + <name/> + <sourceDirectory/> + <includes> + <include> + </includes> + <excludes> + <exclude> + </excludes> + <debug/> + <exceptions/> + <rtti/> + <optimize/> + <multiThreaded/> + <defines> + <define/> + </defines> + <clearDefaultDefines/> + <undefines> + <undefine/> + </undefines> + <clearDefaultUndefines/> + <includePaths> + <includePath/> + </includePaths> + <systemIncludePaths> + <systemIncludePath/> + </systemIncludePaths> + <options> + <option/> + </options> + <clearDefaultOptions/> + </cpp> + + <c> + ... same as for <cpp> + </c> + + <fortran> + ... same as for <cpp> + </fortran> + + <java> + <include/> + <includePaths> + <includePath/> + </includePaths> + <link/> + <runtimeDirectory/> + <runtime/> + </java> + + <javah> + <name/> + <bootClassPaths> + <bootClassPath/> + </bootClassPaths> + <classPaths> + <classPath/> + </classPaths> + <jniDirectory/> + <classDirectory/> + <includes> + <include> + </includes> + <excludes> + <exclude> + </excludes> + </javah> + + <link/> +</configuration> ++-- + + +* {arch} + + The Architecture for which we produce the native library. Examples are +i386, x86, ppc, ppc64, etc... Default is the system property os.arch. + +* {os} + + The Operating System for which we produce the native library. Examples +are Windows, Linux, MacOSX, SunOS, ... Default is derived from os.name, without spaces and +in the case of Windows generalized. + +* {javaHome} + + The location of the Java installation. Default is derived from the system +property java.home, corrected for MacOSX. + +* {aol} + + The Architecture-OS-Linker qualifier. Default is composed from the arch, +os and linker.name value. + +* {resourceDirectory} + + Directory with NAR related resources. Used by the nar-resources goal, which +copies resources over to the target area. Defaults to ${basedir}/src/nar/resources. + +* {resourceBinDir} + + Directory with binaries, relative to ${resourceDirectory}. Defaults to bin. + +* {resourceIncludeDir} + + Directory with includes, relative to ${resourceDirectory}. Defaults to include. + +* {resourceLibDir} + + Directory with libraries, relative to ${resourceDirectory}. Defaults to lib. + +* {maxCores} + + Specifies the maximum number or Cores/CPUs to use for compilation. +If set to 0 it will use all the Cores/CPUs available. + +* {targetDirectory} + + Directory for all NAR related output. +Defaults to "${project.build.directory}/nar" for "compile" goal +Defaults to "${project.build.directory}/test-nar" for "compile-test" goal + +* {output} + + Name of the output. Default is ${project.artifactId}-${project.version}. + +* {failOnError} + + Fail on compilation/linking error. Default is true. + +* {runtime} + + Sets the type of runtime library, possible values "dynamic", "static". +Default is dynamic. + +* {libtool} + + Set use of libtool. If set to true, the "libtool " will be prepended to +the command line for compatible compilers/linkers. Default is false. + +* {libraries} + + Section to specify what type or libraries to create. For each library you may specify: + + [type] The type of the library: shared, static, jni, plugin, executable. Default is shared. + + [linkCPP] Specifies if the stdc++ library should be linked with. Default is true. + + [linkFortran] Specifies if the fortran library should be linked with. Default is false. + + [narSystemPackage] If specified a NarSystem class will be generated in this package and + added to the main jar artifact. The NarSystem class contains the following methods: + + * loadLibrary() - which will load the <artifact>-<version> JNI library. + + [narSystemName] Specifies the NarSystem class. Defaults to NarSystem. + + [narSystemDirectory] Specifies the NarSystem source directory. Defaults to target/nar/nar-generated. + + [] + + [run] If true will run this executable (only if type is executable). + + [args] List of arguments to be provided to executable. + + [] + +* {tests} + + Section to specify which test executables should be created. For each test you may specify: + + [name] Name of the executable. + + [link] Type of linking to be used: shared or static. Default is shared. + + [run] If true will run this test + + [args] List of arguments to be provided to test. + + [] + +* {linker} + + Section to specify parameters for the linker. + +** {linker name} + + The Linker. Some choices are: "msvc", "g++", "CC", "icpc", ... + Default is Architecture OS specific. + +** {linker incremental} + + Enables incremental linking. Default is false. + +** {linker map} + + Enables the production of a map file. Default is false. + +** {linker options} + + Additional options for the linker. + Defaults to AOL specific values. + +** {linker clearDefaultOptions} + + Clear options specified in AOL properties. + +** {linker libs} + + Adds libraries to the linker. For each lib you have to specify: + + [name] Name of the library, or a dependency groupId:artifactId if this library contains sublibraries + + [type] Type of linking for this library. Default is shared. + + [directory] Location for this library. + + [] + +** {linker sysLibs} + + Adds system libraries to the linker. For each syslib you have to specify: + + [name] Name of the system library + + [type] Type of linking for this system library. Default is shared. + + [] + + +* {cpp} + + Section to specify parameters for the c++ compiler. + +** {cpp name} + + The name of the compiler. Some choices are: "msvc", "g++", "gcc", "CC", "cc", "icc", "icpc", ... + Default is AOL specific. + +** {cpp sourceDirectory} + + Source directory for native files + +** {cpp includes} + + Include patterns for sources, relative to sourceDirectory in "ant" style. + +** {cpp excludes} + + Exclude patterns for sources, relative to sourceDirectory in "ant" style. + +** {cpp debug} + + Compile with debug information. Default is false. + +** {cpp exceptions} + + Enables generation of exception handling code. Default is true. + +** {cpp rtti} + + Enables run-time type information. Default is true. + +** {cpp optimize} + + Sets optimization. + Possible choices are: "none", "size", "minimal", "speed", "full", "aggressive", "extreme", "unsafe". + Default is none. + +** {cpp multiThreaded} + + Enables or disables generation of multithreaded code. + Default value: false, except on Windows. + +** {cpp defines} + + Additional list of defines. + +** {cpp clearDefaultDefines} + + Clear the defines specified in AOL properties. + +** {cpp undefines} + + Additional list of undefines. + +** {cpp clearDefaultUndefines} + + Clear undefines specified in AOL properties. + +** {cpp includePaths} + + Include Paths, relative to ${baseDir}. + Defaults to "${sourceDirectory}/include" + +** {cpp systemIncludePaths} + + System Include Paths, which are added at the end of all include paths + +** {cpp options} + + Additional options for the C++ compiler. Some of these options can be set by specific tags (debug, rtti, ...). + Defaults to AOL specific values. + +** {cpp clearDefaultOptions} + + Clear options specified in AOL properties. + +* {c} + + Same definitions as for \<cpp\> + + +* {fortran} + + Same definitions as for \<cpp\> + + +* {java} + + Section to specify parameters for java + +** {java include} + + Add Java includes to includepath. Default is false. + +** {java includePaths} + + List of Java Include Paths, relative to javaHome. + Defaults to: "javaHome/include" and "javaHome/include/os-specific". + +** {java link} + + Add Java Runtime to linker. Default is false. + +** {java runtimeDirectory} + + Relative path from javaHome to the java runtime to link with. + Defaults to AOL specific value. + +** {java runtime} + + Name of the runtime. Default is jvm. + +* {javah} + + Section to specify parameters for javah + +** {javah name} + + Javah command to run. + +** {javah bootClassPaths} + + List of boot class paths. By default none. + +** {javah classPaths} + + List of classpaths. By default the classDirectory directory is included and all dependent classes. + +** {javah jniDirectory} + + The target directory into which to generate the output. + +** {javah classDirectory} + + The class directory to scan for class files with native interfaces. + +** {javah includes} + + The set of files/patterns to include, relative to classDirectory/sourceDirectory. Defaults to "**/*.class" + +** {javah excludes} + + A list of exclusion filters, relative to classDirectory/sourceDirectory. Defaults to none. + + diff --git a/src/site/apt/cpptasks.apt b/src/site/apt/cpptasks.apt new file mode 100644 index 0000000..55704cb --- /dev/null +++ b/src/site/apt/cpptasks.apt @@ -0,0 +1,88 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +CppTasks + + To handle the variety of architectures, compilers and linkers, the NAR Plugin uses +the {{{http://ant-contrib.sourceforge.net/cc.html}cpptasks}} library available +from {{{http://ant-contrib.sourceforge.net/}ant-contrib}}. +This library allows to specify compilers and linkers from ant (and thus from maven) +and unifies most common options for those compilers and linkers. + + The NAR Plugin uses cpptasks 1.0 beta 4 from +{{{http://sourceforge.net/project/showfiles.php?group_id=36177}sourceforge}} +with some minor extensions: + ++-- +** Misc. +- [src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java] no more need for -prebind as of 10.4 +- [src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java] removed trailing space after "-framework" to avoid quoting +- [src/net/sf/antcontrib/cpptasks/gcc/GppLinker.java] added -shared-libgcc/-static-libgcc for linking gcc and c++. +- [src/net/sf/antcontrib/cpptasks/gcc/GccLinker.java] added -dynamic as a valid option to GccLinker +- [src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java] no -Bstatic for Darwin and no -Bdynamic for framework +- [src/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java] removed addition of quotes. +- [src/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java] added missing code for -fno-exceptions +- [src/net/sf/antcontrib/cpptasks/CCTask.java] added log statement to identify linker and compiler +- [src/net/sf/antcontrib/cpptasks/gcc/GppLinker.java] g++ linking now includes option -fexceptions +- [src/net/sf/antcontrib/cpptasks/CommandLineLinker] use absolute paths for filenames if they are shorter than relative paths to overcome windows file length limit. +- [src/net/sf/antcontrib/cpptasks/CCTask.java] added thread to keep progress + +** -fno-rtti changes +- [src/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java] removed -fno-rtti flag +- [src/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java] only add -fno-rtti for g++ and c++ + +** Launch process change +- [src/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java] rewrote the launching of subprocesses (NARPLUGIN-71). +- [src/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java] added protection against null return of run() method. + +** libstdc++ linking +- [src/net/sf/antcontrib/cpptasks/CCTask.java] added method to link with CPP +- [src/net/sf/antcontrib/cpptasks/compiler/LinkType.java] added method to link with CPP +- [src/net/sf/antcontrib/cpptasks/compiler/gcc/GppLinker.java] link with or without CPP + +** jni libraries (MacOS X) +- [src/net/sf/antcontrib/cpptasks/OutputTypeEnum.java] added jni +- [src/net/sf/antcontrib/cpptasks/compiler/LinkType] add jni as type +- [src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker] added jni +- [src/net/sf/antcontrib/cpptasks/gcc/GccLinker.java] add jni as type and special linker for MacOS X to output jnilib files. +- [src/net/sf/antcontrib/cpptasks/gcc/GppLinker.java] add jni as type and special linker for MacOS X to output jnilib files. + +** gfortran compiler +- [src/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java] added gfortran compiler +- [src/net/sf/antcontrib/cpptasks/CompilerEnum.java] added gfortran compiler + +** intel compilers name change +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux32CLinker.java] added (icpc) +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux32Compiler.java] added (icpc) +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux64CLinker.java] added (ecpc) +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux64Compiler.java] added (ecpc) +- [src/net/sf/antcontrib/cpptasks/LinkerEnum.java] added and changed linkers +- [src/net/sf/antcontrib/cpptasks/CompilerEnum.java] added and changed compilers. +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java] links to IntelLinux32CLinker. +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java] links to IntelLinux64CLinker. +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java] changed linker name from icc to icpc for version 8.1 of Intel Compilers. +- [src/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java] changed linker name from ecc to ecpc for version 8.1 of Intel Compilers. + +** sun c and fortran compiles +- [src/net/sf/antcontrib/cpptasks/sun/ForteCCompiler.java] added (suncc) +- [src/net/sf/antcontrib/cpptasks/sun/ForteF77Compiler.java] added (sunf77) +- [src/net/sf/antcontrib/cpptasks/CompilerEnum] Added the above (suncc, sunf77). + +** bug [ 1109917 ] g++ linker does not add runtime w/o other libs referenced +- [src/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker] always call addLibrarySets + +** bug [ 795683 ] cpptasks speedup +- [src/net/sf/antcontrib/cpptasks/DependencyTable.java] cpptasks speedup +- [src/net/sf/antcontrib/cpptasks/DependencyInfo.java] cpptasks speedup ++-- + + You can find the latest of our mods in our svn repository: + ++-- +svn co svn://svn.freehep.org/svn/misc/trunk/cpptasks ++-- + diff --git a/src/site/apt/faq.apt b/src/site/apt/faq.apt new file mode 100644 index 0000000..ec1796f --- /dev/null +++ b/src/site/apt/faq.apt @@ -0,0 +1,50 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +Frequently Asked Questions + + [Why does the nar-package goal run before the (general) jar goal] +The nar-package goal generates the nar.properties file which needs to +be included in the general jar artifact. + + [Why does the nar plugin produce both a jar artifact and an + attached -noarch.nar artifact. Could these two not be combined?] +The jar artifact contains only java classes and gets added to the classpath. +It needs no further processing. The -noarch.nar artifact contains include +files and needs to be unpacked to be useful for the native compilers. +It does not need to be added to the classpath. Combining the two artifacts +would complicate matters. + + [I use the nar-plugin to create a JNI type library. How do I load this library + from my code?] +The JNI library is strictly connected to the corresponding java code in the +main artifact (jar file). Since the main artifact has a version number, we decided +that the JNI library should have the same version number. If you add the subtag +<packageName> to the <library> tag, the nar-plugin will generate a NarSystem +class for you which will load the library. Assuming you specified com.mycompany.mypackage +as packageName, then you need to add the following code to the class with the native +methods: + ++-- +import com.mycompany.mypackage.NarSystem + +public class ... { + + ... + + static { + NarSystem.loadLibrary(); + } + + ... + +} ++-- + + + +
\ No newline at end of file diff --git a/src/site/apt/intro.apt b/src/site/apt/intro.apt new file mode 100644 index 0000000..4b641a1 --- /dev/null +++ b/src/site/apt/intro.apt @@ -0,0 +1,243 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +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.html}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-download}nar-download}} + + [[2]] {{{#nar-system-generate}nar-system-generate}} + + [[3]] {{{#nar-unpack}nar-unpack}} + + [[4]] {{{#nar-resources}nar-resources}} + + [[5]] {{{#nar-javah}nar-javah}} + + [[6]] {{{#nar-compile}nar-compile}} + + [[7]] {{{#nar-testCompile}nar-testCompile}} + + [[8]] {{{#nar-test}nar-test}} + + [[9]] {{{#nar-package}nar-package}} + + [[10]] {{{#nar-integration-test}nar-integration-test}} + + [[11]] {{{#install}install (standard maven goal)}} + + [[12]] {{{#deploy}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.html}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.html}configuration}}. + + The name of the linker is looked up in a 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-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, see {{{nar-dependencies.html} +nar-dependencies}}. By the time this goal is running maven will have already downloaded +all dependent jar 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-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 goals only executed +if you produce a JNI library and you specify a <packageName> as subtag of <library>. The NarSystem +class will then end up in this package. + +* {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 local repository. A flag is set not to download and unpack this nar file again, +except if it is a SNAPSHOT artifact. <<TBD The actual nar file is deleted to preserve diskspace.>> + +* {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-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>>>. +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-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 the cpptasks from the ant-contrib +project, with some minor improvements and additions of compilers, see {{{cpptasks.html}cpptasks}}. +Most of the settings for cpptasks, such as compiler, linker, options and include dirs are available +through the NAR plugin, see {{{configuration.html}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>>>. + + * only 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 freehep.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-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 the cpptasks from the ant-contrib +project, with some minor improvements and additions of compilers, see {{{cpptasks.html}cpptasks}}. +Most of the settings for cpptasks, such as compiler, linker, options and include dirs are available +through the NAR plugin, see {{{configuration.html}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 freehep.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.html} + nar-dependencies}}. + + * \<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 freehep.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 only consists +in their full form on the server and are never unpacked on the server. + diff --git a/src/site/apt/lifecycle.apt b/src/site/apt/lifecycle.apt new file mode 100644 index 0000000..3fd11cd --- /dev/null +++ b/src/site/apt/lifecycle.apt @@ -0,0 +1,48 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +NAR Lifecycle + + The NAR lifecycle copies the default Maven lifecycle and adds native goals to its phases. +The table below shows the different phases of the NAR Lifecycle and the goals (including +standard maven goals) attached to them. The order is left to right, top to bottom. + +*------------------------+-------------------------------------------+ +| <Phase> | <Goals (NAR Goals in bold)> | +*------------------------+-------------------------------------------+ +| generate-sources | <<nar-download>>, <<nar-system-generate>> | +*------------------------+-------------------------------------------+ +| process-sources | <<nar-unpack>> | +*------------------------+-------------------------------------------+ +| process-resources | resources, <<nar-resources>> | +*------------------------+-------------------------------------------+ +| compile | compile, <<nar-javah>> | +*------------------------+-------------------------------------------+ +| process-classes | <<nar-compile>> | +*------------------------+-------------------------------------------+ +| process-test-resources | testResources | +*------------------------+-------------------------------------------+ +| test-compile | testCompile, <<nar-testCompile>> | +*------------------------+-------------------------------------------+ +| test | test, <<nar-test>> | +*------------------------+-------------------------------------------+ +| package | <<nar-package>>, jar | +*------------------------+-------------------------------------------+ +| integration-test | <<nar-integration-test>> | +*------------------------+-------------------------------------------+ +| install | install | +*------------------------+-------------------------------------------+ +| deploy | deploy | +*------------------------+-------------------------------------------+ + + + The NAR plugin attaches the nar files it produces to the main artifact (jar) so the standard +install and deploy plugins of maven do their job. + + The nar-assembly goal is not part of the lifestyle and should be called independently. + +
\ No newline at end of file diff --git a/src/site/apt/narDependencies.apt b/src/site/apt/narDependencies.apt new file mode 100644 index 0000000..526bc7c --- /dev/null +++ b/src/site/apt/narDependencies.apt @@ -0,0 +1,54 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +NAR Dependencies + + Dependencies on other NARs are handled by the standard maven dependency mechanism. +The type for NAR files is <<<nar>>>, however to ease the inclusion of Java code and +lookup of properties any nar file is always published as an attached artifact +to a jar artifact. A nar dependency therefore becomes a jar dependency and is +declared in the following way: + ++-- +<project> + ... + <dependencies> + <dependency> + <groupId>dependent-group</groupId> + <artifactId>dependent-artifact</artifactId> + <version>dependent-version</version> + </dependency> + </dependencies> +</project> ++-- + + as is any other jar dependency. Maven will automatically download this jar file +for any goal that requires it. + + The NAR plugin knows this is a nar dependency +by looking inside the jar file for a properties file with the following name: + ++-- +META-INF/nar/groupId/artifactId/nar.properties ++-- + + This file is normally generated in the nar-package goal for pickup by +the standard package goal to be included in the jar file. +<<TBD there is no way to include a hand-written file>>. + + The file may contain the following properties: + +*---------------------------+--------------------+---------------------------------------+ +| <<Property>> | <<Default-Value>> | <<Description>> | +*---------------------------+--------------------+---------------------------------------+ +| nar.noarch | | Comma separated list of architecture independent nars to download. Each entry consists of groupId:artifactId:type:classifier, for example: ch.cern:cernlib:nar:noarch | +*---------------------------+--------------------+---------------------------------------+ +| nar.static | | Comma separated list of static nar files to download. Each entry consists of groupId:artifactId:type:classifier. $\{aol\} can be used to be replaced by the current aol value, for example: ch.cern:cernlib:nar:$\{aol\}-static | +*---------------------------+--------------------+---------------------------------------+ + + + <<TBD more values are possible >> diff --git a/src/site/apt/narLibrary.apt b/src/site/apt/narLibrary.apt new file mode 100644 index 0000000..98d4a11 --- /dev/null +++ b/src/site/apt/narLibrary.apt @@ -0,0 +1,109 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +NAR Library + + Other plugins may need to use some of the functionality of the NAR Plugin, +such as downloading and unpacking. The NAR Plugin therefore groups most of +its functionality into the NAR Manager and allows other plugins and the NAR +Plugin itself to call on the NAR Manager. + + The {{{http://java.freehep.org/freehep-swig-plugin}SWIG Plugin}} which needs +the swig native executable uses the NAR Manager to download, unpack and call +the executable. + + To use the NAR Manager, see the {{{apidocs/index.html}API Docs}}, add the +following to your POM file: + ++-- +<project> + ... + <dependencies> + ... + <dependency> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <version>2.0-alpha-2-SNAPSHOT</version> + </dependency> + </dependencies> +</project> ++-- + + and use the code with the following snippet: + ++-- +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; +import org.freehep.maven.nar.Linker; +import org.freehep.maven.nar.NarManager; +import org.freehep.maven.nar.NarUtil; + +/** + * Description... + * + * @goal your-goal + * @phase your-phase + * @requiresDependencyResolution compile + */ +public class YourMojo extends AbstractMojo { + + /** + * Level of logging messages, 0 is minimum. + * + * @parameter expression="${logLevel}" default-value="0" + */ + private int logLevel; + + /** + * @parameter expression="${localRepository}" + * @required + * @readonly + */ + private ArtifactRepository localRepository; + + /** + * @parameter expression="${project}" + * @required + * @readonly + */ + private MavenProject project; + + /** + * The Architecture for picking up swig, Some choices are: "x86", "i386", + * "amd64", "ppc", "sparc", ... Defaults to ${os.arch} + * + * @parameter expression="${os.arch}" + * @required + */ + private String architecture; + + /** + * The Operating System for picking up swig. Some choices are: "Windows", + * "Linux", "MacOSX", "SunOS", ... Defaults to a derived value from + * ${os.name} + * + * @parameter expression="" + */ + private String os; + + private NarManager narManager; + + public void execute() throws MojoExecutionException, MojoFailureException { + + os = NarUtil.getOS(os); + // FIXME, should have some function in NarUtil + Linker linker = new Linker("g++"); + narManager = new NarManager(getLog(), logLevel, localRepository, project, + architecture, os, linker); + + ... DO WHATEVER YOU NEED WITH THE NarManager + } +} ++-- diff --git a/src/site/apt/philosophy.apt b/src/site/apt/philosophy.apt new file mode 100644 index 0000000..ce41e2b --- /dev/null +++ b/src/site/apt/philosophy.apt @@ -0,0 +1,311 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +NAR Philosophy + + In the NAR plugin we follow Maven's main principles: + + * {{{#Convention over configuration}Convention over configuration}} + + * {{{#Reuse of build logic}Reuse of build logic}} + + * {{{#Declarative execution}Declarative execution}} + + * {{{#Coherent organization of dependencies}Coherent organization of dependencies}} + + [] + + below we explain how: + + +* {Convention over configuration} + + The NAR Plugin enables a cross-platform build technology for native +artifacts using Maven. Though the user has full flexibility in the choice +of compiler/linker and their options, sensible defaults are provided by the NAR +Plugin. The three primary conventions for the NAR Plugin are: + + * {{{#Standard directory layout for Native projects}Standard directory layout for Native projects}} + + * {{{#A single Native project produces a single output}A single Native project produces a single output}} + + * {{{#Standard naming conventions}Standard naming conventions}} + + [] + + and are detailed below: + + +** {Standard directory layout for Native projects} + + The NAR Plugin assumes to find its native sources and resources +in a directory structure parallel to the java sources. Test sources and +test resources are organized the same way. + ++-- +/yourproject + /src + /main + /java + /resources + /include + /c++ + /c + /fortran + /test + /java + /resources + /include + /c++ + /c + /fortran ++-- + + Organizing the information this way means that it is easy to find, +for both people and the plugins that need to work with them. + + +** {A single Native project produces a single output} + + Maven produces one primary output (jar) per project. For the NAR Plugin +the produced nar files are secondary outputs or attached artifact to the +primary output. There are several reasons why the native artifacts are not +primary outputs: + + * When building a Native library, the object files and the include + headers make a complete set. There is not much use of one without + the other. Object files for one architecture combined in a nar + file are no different than object files for another achitecture, their + functionality is the same, its just for different machines. + Neither the nar file with the include headers nor the nar files + with the machine specific object files is a good primary + output, so both attach to a jar file. + + * When one builds a JNI library one needs both the java code in a jar + file and native code in a shared library. The expected dependency is that + the jar file needs the JNI library. However, javah generates the + necessary header file from java, which would make the JNI library + dependent on the jar file. Since this is impossible it would be + better to attach the JNI library (in its nar file) as a secondary + artifact to the primary jar file. + + * When depending on a native library the user should just specify + the artifactId, groupId and version, and <<not>> the architecture, + os and linker it was build with. The latter is a derived value + of the executable or library one is building at this time. Not + specifying architecture, os and linker also means that the POM + is generic. Since nar files are by default (except for the -noarch + nar) architecture-os-linker specific they need to be secondary + artifacts. + +** {Standard naming conventions} + + When maven produces a jar file its normally named +<<<artifactId-version.jar>>>. The NAR Plugin follows this convention for its +attached artifacts: + + [<<<artifactId-version-noarch.nar>>>] contains the non architecture +specific parts of the native library, such as include headers. + + [<<<artifactId-version-aol-type.nar>>>] contains the architecture +specific parts of the native library, such as the library and object files. +The <aol> is an Architecture-OS-Linker qualifier, for example: +ppc-MacOSX-g++. The <type> specifies what binding the library is, for +example: shared, static or jni. + + [] + + Since the java compiler has a unified interface there is no need +for any naming conventions here. Native compilers and linkers on different +platforms tend to have radically different interfaces (command line options) +so these were unified, allowing the user to switch on exception handling +and debugging with the same tag in the configuration no matter which +platform the NAR Plugin is running on. An example is below: + ++-- +... +<plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <configuration> + <cpp> + <exceptions>false</exceptions> + <debug>true</debug> + </cpp> + </configuration> +</plugin> +... ++-- + + +* {Reuse of build logic} + + The NAR Plugin provides multiple goals organized in the "nar" lifecycle. +The "nar" lifecycle integrates nicely with the default "jar" lifecycle to +build both jar and nar artifacts in parallel. Each of the NAR Plugin goals +can of course also be configured separately if needed. + + Most NAR goals are executed using the NarManager, which provides an API +that can also be used by other plugins when they need to deal with +NAR artifacts. + + +* {Declarative execution} + + All logic in Maven is setup in a declarative fashion using the Project +Object Model (POM). The NAR Plugin can be configured inside this model. +Moreover the "nar" lifecycle can be used to automatically integrate +all the NAR Plugin goals with the goals of the default "jar" lifecycle. + +** NAR's project object model (POM) + + The POM below is an example of how to compile, link and test a native +shared library, which depends on a native math library (nmath). + ++-- +<project> + <modelVersion>4.0.0</modelVersion> + <groupId>com.mycompany.app</groupId> + <artifactId>my-app</artifactId> + <packaging>nar</packaging> + <version>1.0-SNAPSHOT</version> + <build> + <plugins> + <plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <version>nar-version-number</version> + <extensions>true</extensions> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.freehep</groupId> + <artifactId>nmath</artifactId> + <version>4.5.1</version> + </dependency> + </dependencies> +</project> ++-- + + This POM will allow you to compile, link and test the java and native code +in the project. The crucial part of the POM is the inclusion of the NAR +plugin as an extension and the declaration of the "nar" packaging. The two will +call the NAR Plugin goals as specified in the lifecycle. + + For this POM the NAR Plugin will download and unpack the noarch and aol parts of the +org.freehep nmath library version 4.5.1, for the platform you are running on. + + Maven's Super POM is used for most of the default behaviour +and the NAR Plugin's {{{aol.html}AOL Properties}} are used for native defaults. + + +** NAR's build lifecycle + + Maven's default build lifecycle, "jar", allows one to execute plugin goals +as part of it, but this necessitates declaration of separate goals in each +POM. To simplify the building of native artifacts we chose to define a "nar" +lifecycle which calls all the goals the "jar" lifecycle has, interleaved with +the goals of the NAR Plugin. + + +* {Coherent organization of dependencies} + + Maven uses a local repository to resolve its dependencies. If not found +one or more remote repositories are consulted to find a dependency. If found +the dependency is downloaded to the local repository and used from there by +any of the plugins. + + The NAR Plugin uses the same organization of dependencies and repositories. +Note that the dependency declared in the example above is a standard "jar" +dependency. It becomes a NAR depenency only because it contains the nar.properties +file and the NAR Plugin is configured for this project. When a user executes +install or deploy on a NAR project the jar file with its attached nar artifacts +will be installed in the local repository or deployed in the remote repository. + + A remote repository for the native math library would probably look +like this (note the support for multiple platforms and multiple library bindings): + ++-- +remoterepo/ + org/ + freehep/ + nmath/ + 4.5.1/ + nmath-4.5.1.pom + nmath-4.5.1.pom.sha1 + nmath-4.5.1.jar + nmath-4.5.1.jar.sha1 + nmath-4.5.1-noarch.nar + nmath-4.5.1-noarch.nar.sha1 + nmath-4.5.1-MacOSX-g++-static.nar + nmath-4.5.1-MacOSX-g++-static.nar.sha1 + nmath-4.5.1-MacOSX-g++-shared.nar + nmath-4.5.1-MacOSX-g++-shared.nar.sha1 + nmath-4.5.1-Linux-g++-shared.nar + nmath-4.5.1-Linux-g++-shared.nar.sha1 + nmath-4.5.1-Windows-msvc-shared.nar + nmath-4.5.1-Windows-msvc-shared.nar.sha1 + ... ++-- + + When a NAR dependency is encountered the jar file is already downloaded into +the local repository by maven itself. The nar-download goal will download any +attached NAR artifacts into the local repository and store them alongside the +jar file and the POM. Note that for these jar and nar files there is just one +POM, since it is just one artifact. If the nar files are already in the local +repository, due to someone calling nar-install on them, no extra download occurs. + + Now that the POM, jar and nar files are all in the local repository, the +nar-unpack goal unpacks the nar files. This is necessary because none of the +native compiler/linker tools understands nar files, so an unpacked directory +structure should be created. Unpacking only happens in the local repository. +A remote repository <<never>> contains an unpacked nar file. If unpacking was +already done, then no action is taken by the nar-unpack goal, unless the +artifact is a SNAPSHOT. + + The local repository for the native math library may look similar to this +if we were running on a MacOS X PowerPC system (Note the unpacked nar directory +and nar only for one platform): + ++-- +repository/ + org/ + freehep/ + nmath/ + 4.5.1/ + nmath-4.5.1.pom + nmath-4.5.1.pom.sha1 + nmath-4.5.1.jar + nmath-4.5.1.jar.sha1 + nmath-4.5.1-noarch.nar + nmath-4.5.1-noarch.nar.sha1 + nmath-4.5.1-MacOSX-g++-shared.nar + nmath-4.5.1-MacOSX-g++-shared.nar.sha1 + ... + nar/ + bin/ + ppc-MacOSX-g++/ + NMath + include/ + nmath/ + NMath.hh + data/ + NMath.data + lib/ + ppc-MacOSX-g++/ + shared/ + libNMath.so + libNMathExtra.so ++-- + + The usage of local repository by the NAR Plugin works seamlessly with the +usage of it by other Maven plugins. The SWIG Plugin for instance downloads +the native swig executable (wrapped in a NAR artifact), installs and unpacks +it in the local repository and then uses the executable in the bin directory +location. diff --git a/src/site/apt/usage.apt b/src/site/apt/usage.apt new file mode 100644 index 0000000..c64b9f3 --- /dev/null +++ b/src/site/apt/usage.apt @@ -0,0 +1,228 @@ + --- +FreeHEP NAR Plugin + --- + --- +Mark Donszelmann + --- + +Usage + + The following fragments can be used to execute the NAR plugin to compile +and link native code. + +* Create a Shared Library (but not a JNI library). + ++-- +<project> + ... + <packaging>nar</packaging> + ... + <build> + <plugins> + <plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <version>nar-version-number</version> + <extensions>true</extensions> + </plugin> + </plugins> + </build> +</project> ++-- + +* Create a JNI Library + ++-- +<project> + ... + <packaging>nar</packaging> + ... + <build> + <plugins> + <plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <libraries> + <library> + <type>jni</type> + <packageName>com.mycompany.mypackage</packageName> + </library> + </libraries> + </configuration> + </plugin> + </plugins> + </build> +</project> ++-- + +* Create a JNI Library without linking to C++ + + It is possible to write your JNI code in C++, use the C++ compiler +to compile it and then link it only with the C library (as long as +you have not used any C++ library calls). Note the two tags +to disable exceptions and not link with C++. + ++-- +<project> + ... + <packaging>nar</packaging> + ... + <build> + <plugins> + <plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <cpp> + <exceptions>false</exceptions> + </cpp> + <libraries> + <library> + <type>jni</type> + <linkCPP>false</linkCPP> + </library> + </libraries> + </configuration> + </plugin> + </plugins> + </build> +</project> ++-- + +* Create a JNI Library using SWIG generated code + + Since SWIG already generated the .h file normally +generated by javah, we exclude this file from javah. +We also include the compilation and linking with java. +The example also shows how to configure the +{{{http://java.freehep.org/freehep-swig-plugin}freehep-swig-plugin}}. + ++-- +<project> + ... + <packaging>nar</packaging> + ... + <build> + <plugins> + <plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-swig-plugin</artifactId> + <extensions>true</extensions> + <executions> + <execution> + <id>swig</id> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <cpp>true</cpp> + <packageName>org.domain.packagename</packageName> + <source>Module.swg</source> + </configuration> + </execution> + </executions> + </plugin> + ... + <plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <configuration> + <java> + <include>true</include> + </java> + <javah> + <excludes> + <exclude>**/ModuleJNI.class</exclude> + </excludes> + </javah> + <libraries> + <library> + <type>jni</type> + </library> + </libraries> + </configuration> + </plugin> + </plugins> + </build> +</project> ++-- + +* Assemble libraries made on different platforms for distribution + + This example shows how to download, unpack and assemble +the already deployed machine dependent libraries. +It also shows the setup of the standard maven-assembly-plugin +to pick up the unpacked libraries. + + Note there is no "nar" packaging as the normal packaging for +assemblies would be "pom". + ++-- +<project> + ... + <packaging>pom</packaging> + ... + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <!-- NOTE 2.1 fails --> + <version>2.0.1</version> + <configuration> + <descriptors> + ... + <descriptor>src/main/assembly/x86-Windows-msvc.xml</descriptor> + <descriptor>src/main/assembly/ppc-MacOSX-g++.xml</descriptor> + <descriptor>src/main/assembly/i386-Linux-g++.xml</descriptor> + </descriptors> + </configuration> + </plugin> + ... + <plugin> + <groupId>org.freehep</groupId> + <artifactId>freehep-nar-plugin</artifactId> + <configuration> + <classifiers> + <classifier>x86-Windows-msvc</classifier> + <classifier>ppc-MacOSX-g++</classifier> + <classifier>i386-Linux-g++</classifier> + </classifiers> + </configuration> + <executions> + <execution> + <goals> + <goal>nar-download</goal> + <goal>nar-unpack</goal> + <goal>nar-assembly</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> ++-- + + The i386-Linux-g++ assembly descriptor is below: + ++-- +<assembly> + <id>i386-Linux-g++</id> + <formats> + <format>tar.gz</format> + </formats> + <fileSets> + <fileSet> + <directory>target/nar/lib/i386-Linux-g++/jni</directory> + <outputDirectory>lib/i386-Linux-g++</outputDirectory> + <includes> + <include>*</include> + </includes> + </fileSet> + </fileSets> +</assembly> ++-- + diff --git a/src/site/resources/NARPlugin.ppt b/src/site/resources/NARPlugin.ppt Binary files differnew file mode 100644 index 0000000..4ac2ae5 --- /dev/null +++ b/src/site/resources/NARPlugin.ppt diff --git a/src/site/site.xml b/src/site/site.xml new file mode 100644 index 0000000..c2b6814 --- /dev/null +++ b/src/site/site.xml @@ -0,0 +1,59 @@ +<project name="freehep"> + <bannerLeft> + <name>FreeHEP NAR Plugin</name> +<!-- <src>http://maven.apache.org/images/apache-maven-project.png</src> --> +<!-- FIXME, should this be substituted by some properties --> + <href>http://java.freehep.org/freehep-nar-plugin</href> + </bannerLeft> + + <bannerRight> + <name>FreeHEP</name> + <src>http://java.freehep.org/images/sm-freehep.gif</src> + <href>http://java.freehep.org</href> + </bannerRight> + + <body> + <links> + <item name="NAR Plugin for Maven1" href="http://java.freehep.org/maven1.x/freehep-nar-plugin"/> + <item name="FreeHEP 1.x" href="http://java.freehep.org/freehep1.x"/> + <item name="FreeHEP 2.x" href="http://java.freehep.org/"/> + <item name="Maven 2" href="http://maven.apache.org/maven2/"/> + </links> + + <menu name="Overview"> + <item name="Introduction" href="intro.html"/> + <item name="Philosophy" href="philosophy.html"/> + <item name="Presentation (pdf)" href="NARPlugin.pdf"/> + <item name="Presentation (ppt)" href="NARPlugin.ppt"/> + </menu> + + <menu name="User Info"> + <item name="Goals" href="plugin-info.html"/> + <item name="Usage" href="usage.html"/> + <item name="Lifecycle" href="lifecycle.html"/> + <item name="Configuration" href="configuration.html"/> + <item name="FAQ" href="faq.html"/> + <item name="AOL Properties" href="aol.html"/> + </menu> + + <menu name="Developer Info"> + <item name="NAR Dependencies" href="narDependencies.html"/> + <item name="Bug Reports" href="http://bugs.freehep.org/browse/NARPLUGIN"/> + <item name="Forum" href="http://forum.freehep.org/index.php?t=threadt&frm_id=14&rid=4"/> + <item name="APIDocs" href="apidocs/index.html"/> + <item name="NAR Library" href="narLibrary.html"/> + <item name="CPPTasks" href="cpptasks.html"/> + <item name="SVN Browse" href="http://java.freehep.org/svn/repobrowser.svn?path=%2ffreehep%2ftrunk%2fmaven-plugins%2ffreehep-nar-plugin/&revision=HEAD"/> + <item name="SVN Repository" href="source-repository.html"/> + </menu> + <menu name="Examples"> + <item name="HelloWorld" href="HelloWorld.html"/> + </menu> + <menu name="Other Information"> + <item name="Maven and other languages" href="http://docs.codehaus.org/display/MAVEN/Support+for+other+languages"/> + </menu> + + ${reports} + + </body> +</project> diff --git a/src/xdocs/nar-dependencies.xml b/src/xdocs/nar-dependencies.xml new file mode 100644 index 0000000..dd9ae8e --- /dev/null +++ b/src/xdocs/nar-dependencies.xml @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<document> + <properties> + <title> NAR Dependencies</title> + <author email="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</author> + </properties> + <body> + <section name="Dependencies on other NARs"> + <p> + Dependencies on other NARs are handled by the maven dependency mechanism. + + The type for NAR files is <code>nar</code>. A NAR dependency is specified + in the following way: + </p> + + <source> +<dependency> + <groupId>DependentGroup</groupId> + <artifactId>DependentArtifact<b>-nar</b></artifactId> + <version>DependentVersion</version> + <type><b>nar</b></type> +</dependency> + </source> + + <p> + The artifactId needs to specify a <code><b>-nar</b></code> suffix since artifactIds need to be unique + and a jar file may exist with the same name. + </p> + + <p> + When a nar dependency is found in the POM, Maven will download the property file : + </p> + <source> +<i>DependentGroup</i>/<b>nar</b>s/<i>DependentArtifact</i><b>-nar</b>-<i>DependentVersion</i>.<b>nar</b> + </source> + <p> + This file is normally generated by the NAR plugin for the DependentArtifact and + may specify the following properties: + </p> + + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>freehep.nar.nars</td> + <td>Space separated list of other nar files to download. + </td> + <td> + <code><i>DependentArtifact</i><b>-nar</b>-<i>DependentVersion</i>.<b>noarch.nar</b> + <i>DependentArtifact</i><b>-nar</b>-<i>DependentVersion</i>.<b>${aol}.nar</b></code> + </td> + </tr> + </table> + <p> + The default files specified for download will have the common and machine-os specific parts in them + respectively. + </p> + + <p> + The NAR plugin will look in the project.properties file followed by the + <i>DependentArtifact</i><b>-nar</b>-<i>DependentVersion</i>.<b>nar</b> file for any of the + following properties: + </p> + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]<i>DependentArtifact</i>-nar.local</td> + <td>Specifies that the DependentArtifact is installed locally (in a different place than the local + repository. The property <code>freehep.nar.nars</code> will be ignored. + One would typically use this for standard libs such as zlib and others.</td> + <td>false</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]<i>DependentArtifact</i>-nar.dir</td> + <td>Specify a local directory where the DependentArtifact libs can be found.</td> + <td></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]<i>DependentArtifact</i>-nar.include</td> + <td>Specify a local directory where the DependentArtifact includes can be found.</td> + <td></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]<i>DependentArtifact</i>-nar.libs</td> + <td>Specify the libs to use for linking</td> + <td><code>${DependentArtifact}-nar-${DependentVersion}</code></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]<i>DependentArtifact</i>-nar.local.libs</td> + <td>Specify the libs to use for linking if the libs are local</td> + <td><code>${DependentArtifact}-nar.libs</code></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]<i>DependentArtifact</i>-nar.type</td> + <td>Specify the type of linking</td> + <td><code>${freehep.nar.libs.type}</code></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]<i>DependentArtifact</i>-nar.linkLibs</td> + <td>Specify if libraries should be linked with (there are distributions with only include files).</td> + <td>true</td> + </tr> + + <tr> + <td><i>DependentArtifact</i>-nar.<i>AOL</i></td> + <td>Converts one AOL into another. For example: YourLib-nar.i386-Linux-g++=i386-Linux-gcc will + make sure you can link from g++ as well as from gcc to YourLib. YourLib needs to be dsitributed + as a gcc linked lib in this case.</td> + <td>${freehep.nar.aol.name}</td> + </tr> + + </table> + + <p> + If the property <i>DependentArtifact</i>-nar.local is set to true, then no further files will be + downloaded or installed and the properties <i>DependentArtifact</i>-nar.dir and + <i>DependentArtifact</i>-nar.include will be used for compilation and linking with this <i>DependentArtifact</i>. + In the other case the files specified by freehep.nar.nars will be downloaded, installed in + the local repository, unpacked and used for compilation and linking. + Setting <i>DependentArtifact</i>-nar.local allows the user to avoid downloading a library + which is already installed as a non-NAR file somewhere else on his machine. + The other properties are used in both the local and the NAR case. + </p> + <p> + When generating a set of NAR files, the <i>Artifact</i>-nar-<i>Version</i>.nar file will be generated + for you. This file may contain any of the properties listed above. The NAR plugin generates the + properties freehep.nar.nars and <i>Artifact</i>-nar.linkLibs. Any other properties can be specified + in the nar.properties file in the artifact's top directory (alongside project.properties) and will + be concatenated to the generated nar file. + </p> + </section> + + + + </body> +</document>
\ No newline at end of file diff --git a/src/xdocs/properties.xml b/src/xdocs/properties.xml new file mode 100644 index 0000000..28bcbf5 --- /dev/null +++ b/src/xdocs/properties.xml @@ -0,0 +1,737 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<document> + + <properties> + <title>FreeHEP NAR Plugin Properties</title> + <author email="Mark.Donszelmann@slac.stanford.edu">Mark Donszelmann</author> + </properties> + + <body> + <section name="NAR Properties"> + <p> + Below are the properties by group for the NAR plugin. The properties with + the <code>[<i>arch.[os.[linker.]</i>]</code> prefix can either be set in general, + architecture specific, architecture-os specific or architecture-os-linker specific. + The latter overruling the former ones. The defaults for these combiations + are listed in two separate tables below. + </p> + + <subsection name="Command Line Flags"> + <table> + <tr> + <th>Flag</th> + <th>Description</th> + </tr> + + <tr> + <td>maven -Dverbose</td> + <td>Output NAR debug stetements</td> + </tr> + + <tr> + <td>maven -X</td> + <td>Output maven debug statements</td> + </tr> + </table> + </subsection> + + <subsection name="General"> + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>freehep.nar.arch</td> + <td>Architecture [<i>arch</i>] (ex: x86, i386, sparc, ...)</td> + <td> + <code>${os.arch}</code> + </td> + </tr> + + <tr> + <td>freehep.nar.os</td> + <td>Operating System [<i>os</i>] (ex: Linux, win32, MacOSX, SunOs, ...)</td> + <td> + <code>${os.name}</code> (Note: no spaces) + </td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>]]freehep.nar.linker</td> + <td><a href="http://ant-contrib.sourceforge.net/linker.html">Linker</a> [<i>linker</i>] + (ex: msvc, g++, CC, ...), but you may use any name here and override it in + the property <i>arch.os.linker.</i>freehep.nar.linker to the real linker name.</td> + <td>Architecture-OS specific, see <a href="#Architecture-OS">below</a>.</td> + </tr> + </table> + </subsection> + + <subsection name="Architecture/OS Independent Settings" > + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>freehep.nar.src</td> + <td>Source file directory</td> + <td><code>src/main/cpp</code></td> + </tr> + + <tr> + <td>freehep.nar.cpp.src.includes</td> + <td>C++ file pattern to include</td> + <td><code>**/*.h **/*.hh **/*.cc **/*.cpp **/*.cxx</code></td> + </tr> + + <tr> + <td>freehep.nar.cpp.src.excludes</td> + <td>C++ file pattern to exclude</td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.c.src.includes</td> + <td>C file pattern to include</td> + <td><code>**/*.h **/*.c</code></td> + </tr> + + <tr> + <td>freehep.nar.c.src.excludes</td> + <td>C file pattern to exclude</td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.fortran.src.includes</td> + <td>Fortran file pattern to include</td> + <td><code>**/*.f **/*.for</code></td> + </tr> + + <tr> + <td>freehep.nar.fortran.src.excludes</td> + <td>Fortran file pattern to exclude</td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.test.src</td> + <td>Test source file directory</td> + <td><code>src/test/cpp</code></td> + </tr> + + <tr> + <td>freehep.nar.compile.includepath</td> + <td><a href="http://ant-contrib.sourceforge.net/includepath.html"> + Include path for compilation</a></td> + <td><code>src/main/include</code></td> + </tr> + + <tr> + <td>freehep.nar.compile.sysincludepath</td> + <td><a href="http://ant-contrib.sourceforge.net/sysincludepath.html"> + System include path for compilation</a></td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.compile.withjava</td> + <td>Adds the Java Virtual Machine include files for compilation</td> + <td>false (automatic if the nar:jni goal is run and headers are generated)</td> + </tr> + + <tr> + <td>freehep.nar.test.compile.includepath</td> + <td><a href="http://ant-contrib.sourceforge.net/includepath.html"> + Include path for compilation of tests</a></td> + <td><code>src/test/include</code></td> + </tr> + + <tr> + <td>freehep.nar.link.withjava</td> + <td>Enables the linking with the Java Virtual Machine</td> + <td><code>${freehep.nar.compile.withjava}</code></td> + </tr> + + <tr> + <td>freehep.nar.jni.classpath</td> + <td>Classpath to add for nar:jni goal</td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.tests</td> + <td>List of test (executables) to be generated</td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.includefilesonly</td> + <td>Generates only common NAR file. Machine-OS specific NAR file will not be made.</td> + <td>false</td> + </tr> + + <tr> + <td>freehep.nar.aol</td> + <td>Architecture-OS-Linker [<i>aol</i>] name, used for naming the machine specific NAR + and used for the destination directory</td> + <td> + <code><i>arch-os-linker</i></code> + </td> + </tr> + + <tr> + <td>freehep.nar.dest</td> + <td>Output directory</td> + <td> + <code>${maven.build.dir}/nar</code> + </td> + </tr> + + <tr> + <td>freehep.nar.test.dest</td> + <td>Test output directory</td> + <td> + <code>${maven.build.dir}/test-nar</code> + </td> + </tr> + </table> + </subsection> + + + <subsection name="Compilers and Linkers" > + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.cpp.compiler</td> + <td><a href="http://ant-contrib.sourceforge.net/compiler.html">C++ Compiler</a></td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.c.compiler</td> + <td><a href="http://ant-contrib.sourceforge.net/compiler.html">C Compiler</a></td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.fortran.compiler</td> + <td><a href="http://ant-contrib.sourceforge.net/compiler.html">Fortran Compiler</a></td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + + <tr> + <td><i>arch.os.linker.</i>freehep.nar.linker</td> + <td><a href="http://ant-contrib.sourceforge.net/linker.html">Real linker name</a></td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + </table> + </subsection> + + + + <subsection name="Unified Compiler and Linker Options" > + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.rtti</td> + <td>Enable Runtime Type Identification</td> + <td>true</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.exceptions</td> + <td>Enable Exception Handling</td> + <td>true</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.runtime</td> + <td><a href="http://ant-contrib.sourceforge.net/cc.html">Use static or dynamic runtime library</a></td> + <td>dynamic</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.optmize</td> + <td><a href="http://ant-contrib.sourceforge.net/cc.html">Set optimization level</a></td> + <td>none</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.multithreaded</td> + <td>Enable multithreading</td> + <td>false</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.incremental</td> + <td>Enable incremental linking</td> + <td>false</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.failonerror</td> + <td>Abort if an error is detected</td> + <td>true</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.libtool</td> + <td>Use libtool to compile and link</td> + <td>false</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.debug</td> + <td>Generate debugging code</td> + <td>false</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.outtype</td> + <td><a href="http://ant-contrib.sourceforge.net/cc.html">Type of library to be generated</a> (use "jni" for native shareable code with java)</td> + <td>static</td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.test.outtype</td> + <td><a href="http://ant-contrib.sourceforge.net/cc.html">Type of test output to be generated</a></td> + <td>executable</td> + </tr> + + </table> + </subsection> + + + <subsection name="Additional Compiler and Linker Options" > + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.compiler.arg.start|mid|end</td> + <td> + <a href="http://ant-contrib.sourceforge.net/compilerarg.html"> + Space delimited list of optional compiler arguments</a>. + <code>start|mid|end</code> specifies the position in the compiler + argument list. + </td> + <td></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.cpp.compiler.arg.start|mid|end</td> + <td> + <a href="http://ant-contrib.sourceforge.net/compilerarg.html"> + Space delimited list of optional cpp compiler arguments</a>. + <code>start|mid|end</code> specifies the position in the compiler + argument list. + </td> + <td></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.c.compiler.arg.start|mid|end</td> + <td> + <a href="http://ant-contrib.sourceforge.net/compilerarg.html"> + Space delimited list of optional c compiler arguments</a>. + <code>start|mid|end</code> specifies the position in the compiler + argument list. + </td> + <td></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.fortran.compiler.arg.start|mid|end</td> + <td> + <a href="http://ant-contrib.sourceforge.net/compilerarg.html"> + Space delimited list of optional fortran compiler arguments</a>. + <code>start|mid|end</code> specifies the position in the compiler + argument list. + </td> + <td></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.linker.arg.start|mid|end</td> + <td> + <a href="http://ant-contrib.sourceforge.net/linkerarg.html"> + Space delimited list of optional linker arguments</a>. + <code>start|mid|end</code> specifies the position in the linker + argument list. + </td> + <td></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.linker.test.arg.start|mid|end</td> + <td> + <a href="http://ant-contrib.sourceforge.net/linkerarg.html"> + Space delimited list of optional linker arguments for creating the test output</a>. + <code>start|mid|end</code> specifies the position in the linker + argument list. + </td> + <td></td> + </tr> + + </table> + </subsection> + + <subsection name="Java Settings" > + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.java.home</td> + <td>Java Home (jdk)</td> + <td> + <code>${java.home}/..</code> + </td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.java.include</td> + <td>Directory to look for include files for jni</td> + <td><code>${freehep.nar.java.home}/include</code></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.java.include.os</td> + <td>OS specific directory to look for include files for jni</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.java.vm</td> + <td>Location to the jvm</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + </table> + </subsection> + + + + <subsection name="File Prefixes, Suffixes and Extensions" > + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.lib.prefix</td> + <td>Prefix for library name</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.static.extension</td> + <td>Extension for static library</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.shared.extension</td> + <td>Extension for shared library</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.plugin.extension</td> + <td>Extension for plugin library</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.executable.extension</td> + <td>Extension for executable output</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + + </table> + </subsection> + + <subsection name="Extra Libraries (please use nar dependencies rather than these)" > + <table> + <tr> + <th>Property</th> + <th>Description</th> + <th>Default Value</th> + </tr> + + <tr> + <td>freehep.nar.libs.type</td> + <td>Type for libraries</td> + <td>static</td> + </tr> + + <tr> + <td>freehep.nar.libs</td> + <td>List of library modules to link against [<i>X</i>]</td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.lib.<i>X</i>.libs</td> + <td>List of library names to link against</td> + <td><i>X</i></td> + </tr> + + <tr> + <td>freehep.nar.lib.<i>X</i>.dir</td> + <td>Directory where to look for <i>X</i></td> + <td><code>${freehep.nar.dest}/lib</code></td> + </tr> + + <tr> + <td>freehep.nar.lib.<i>X</i>.type</td> + <td>Type of library <i>X</i></td> + <td><code>${freehep.nar.libs.type}</code></td> + </tr> + </table> + </subsection> + + <subsection name="NAR packaging" > + <table> + <tr> + <td>[<i>arch.</i>[<i>os.</i>[<i>linker.</i>]freehep.nar.arch.includes</td> + <td>Include these files and libraries in the arch specific nar file</td> + <td>Architecture-OS-Linker specific, see <a href="#Architecture-OS">below</a></td> + </tr> + </table> + </subsection> + </section> + + + + + + <section name="Default values for Architecture and Operating System specific properties"> + <p> + Below are the defaults for the architecture and os specific properties. Each of the property names + is prefixed with the <code>arch.os</code> name as given in the different columns. + </p> + <table> + <tr> + <th>Property</th> + <th>x86.win32</th> + <th>i386.Linux</th> + <th>amd64.Linux</th> + <th>ppc.MacOSX</th> + <th>sparc.SunOS</th> + </tr> + + <tr> + <td>freehep.nar.linker</td> + <td>msvc</td> + <td>g++</td> + <td>g++</td> + <td>g++</td> + <td>CC</td> + </tr> + + <tr> + <td>freehep.nar.java.home</td> + <td></td> + <td></td> + <td></td> + <td><code>${java.home}</code></td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.java.include.os prefixed with <code>freehep.nar.java.home</code></td> + <td>include/win32</td> + <td>include/linux</td> + <td>include/linux</td> + <td></td> + <td>include/solaris</td> + </tr> + + <tr> + <td>freehep.nar.java.vm prefixed with <code>freehep.nar.java.home</code></td> + <td><code>lib</code></td> + <td><code>jre/lib/i386/client</code></td> + <td><code>jre/lib/amd64/server</code></td> + <td>IGNORED, uses "-framework JavaVM"</td> + <td><code>jre/lib/sparc/server</code></td> + </tr> + + <tr> + <td>freehep.nar.multithreaded</td> + <td>true</td> + <td></td> + <td></td> + <td></td> + <td></td> + </tr> + + <tr> + <td>freehep.nar.cpp.compiler</td> + <td>msvc</td> + <td>g++</td> + <td>g++</td> + <td>g++</td> + <td>CC</td> + </tr> + + <tr> + <td>freehep.nar.c.compiler</td> + <td>msvc</td> + <td>gcc</td> + <td>gcc</td> + <td>gcc</td> + <td>suncc</td> + </tr> + + <tr> + <td>freehep.nar.fortran.compiler</td> + <td>df</td> + <td>g77</td> + <td>g77</td> + <td>g77</td> + <td>sunf77</td> + </tr> + + <tr> + <td>freehep.nar.compiler.arg.start</td> + <td>-DWIN32</td> + <td>-DLinux</td> + <td>-DLinux</td> + <td>-DDarwin</td> + <td>-lpthread -DSOLARIS2</td> + </tr> + + <tr> + <td>freehep.nar.linker.arg.start</td> + <td></td> + <td></td> + <td></td> + <td></td> + <td>-lpthread</td> + </tr> + + <tr> + <td>freehep.nar.arch.includes</td> + <td>lib/**/*.lib lib/**/*.dll</td> + <td>lib/**/*.a lib/**/*.so</td> + <td>lib/**/*.a lib/**/*.so</td> + <td>lib/**/*.a lib/**/*.so lib/**/*.dylib lib/**/*.jnilib</td> + <td>lib/**/*.a lib/**/*.so</td> + </tr> + + <tr> + <td>freehep.nar.lib.prefix</td> + <td></td> + <td>lib</td> + <td>lib</td> + <td>lib</td> + <td>lib</td> + </tr> + + <tr> + <td>freehep.nar.static.extension</td> + <td>.lib</td> + <td>.a</td> + <td>.a</td> + <td>.a</td> + <td>.a</td> + </tr> + + <tr> + <td>freehep.nar.shared.extension</td> + <td>.dll</td> + <td>.so</td> + <td>.so</td> + <td>.dylib</td> + <td>.so</td> + </tr> + + <tr> + <td>freehep.nar.plugin.extension</td> + <td>.dll</td> + <td>.so</td> + <td>.so</td> + <td>.bundle</td> + <td>.so</td> + </tr> + + <tr> + <td>freehep.nar.executable.extension</td> + <td>.exe</td> + <td></td> + <td></td> + <td></td> + <td></td> + </tr> + + </table> + </section> + + + <section name="Default values for Architecture, Operating System and Linker specific properties"> + <p> + Below are the defaults for the architecture, os and linker specific properties. Each of the property names + is prefixed with the <code>arch.os.linker</code> name as given in the different columns. + </p> + <table> + <tr> + <th>Property</th> + <th>x86.win32.g++</th> + <th>i386.Linux.icc</th> + <th>i386.Linux.ecc</th> + </tr> + + <tr> + <td>freehep.nar.cpp.compiler</td> + <td>g++</td> + <td>icpc</td> + <td>ecpc</td> + </tr> + + <tr> + <td>freehep.nar.c.compiler</td> + <td>gcc</td> + <td>icc</td> + <td>ecc</td> + </tr> + + <tr> + <td>freehep.nar.fortran.compiler</td> + <td>g77</td> + <td>ifort</td> + <td>ifort (should this be efc?)</td> + </tr> + + </table> + </section> + + + + </body> +</document> |