org.bytedeco.javacpp.tools.BuildMojo.java Source code

Java tutorial

Introduction

Here is the source code for org.bytedeco.javacpp.tools.BuildMojo.java

Source

/*
 * Copyright (C) 2012-2016 Arnaud Nauwynck, Samuel Audet
 *
 * Licensed either under the Apache License, Version 2.0, or (at your option)
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation (subject to the "Classpath" exception),
 * either version 2, or any later version (collectively, 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
 *     http://www.gnu.org/licenses/
 *     http://www.gnu.org/software/classpath/license.html
 *
 * or as provided in the LICENSE.txt file that accompanied this code.
 * 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.
 */

package org.bytedeco.javacpp.tools;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.bytedeco.javacpp.Loader;

/**
 * A Maven Mojo to call the {@link Builder} (C++ header file -> Java class -> C++ JNI -> native library).
 * Can also be considered as an example of how to use the Builder programmatically.
 *
 * @author Arnaud Nauwynck
 * @author Samuel Audet
 */
@Mojo(name = "build", defaultPhase = LifecyclePhase.PROCESS_CLASSES)
public class BuildMojo extends AbstractMojo {

    /** Load user classes from classPath. */
    @Parameter(property = "javacpp.classPath", defaultValue = "${project.build.outputDirectory}")
    String classPath = null;

    /** Load user classes from classPaths. */
    @Parameter(property = "javacpp.classPaths")
    String[] classPaths = null;

    /** Add the path to the "platform.includepath" property. */
    @Parameter(property = "javacpp.includePath")
    String includePath = null;

    /** Add the paths to the "platform.includepath" property. */
    @Parameter(property = "javacpp.includePaths")
    String[] includePaths = null;

    /** Add the path to the "platform.linkpath" property. */
    @Parameter(property = "javacpp.linkPath")
    String linkPath = null;

    /** Add the paths to the "platform.linkpath" property. */
    @Parameter(property = "javacpp.linkPaths")
    String[] linkPaths = null;

    /** Add the path to the "platform.preloadpath" property. */
    @Parameter(property = "javacpp.preloadPath")
    String preloadPath = null;

    /** Add the paths to the "platform.preloadpath" property. */
    @Parameter(property = "javacpp.preloadPaths")
    String[] preloadPaths = null;

    /** Output all generated files to outputDirectory. */
    @Parameter(property = "javacpp.outputDirectory")
    File outputDirectory = null;

    /** Output everything in a file named after given outputName. */
    @Parameter(property = "javacpp.outputName")
    String outputName = null;

    /** Compile and delete the generated .cpp files. */
    @Parameter(property = "javacpp.compile", defaultValue = "true")
    boolean compile = true;

    /** Delete generated C++ JNI files after compilation */
    @Parameter(property = "javacpp.deleteJniFiles", defaultValue = "true")
    boolean deleteJniFiles = true;

    /** Generate header file with declarations of callbacks functions. */
    @Parameter(property = "javacpp.header", defaultValue = "false")
    boolean header = false;

    /** Copy to output directory dependent libraries (link and preload). */
    @Parameter(property = "javacpp.copyLibs", defaultValue = "false")
    boolean copyLibs = false;

    /** Also create a JAR file named {@code <jarPrefix>-<platform>.jar}. */
    @Parameter(property = "javacpp.jarPrefix")
    String jarPrefix = null;

    /** Load all properties from resource. */
    @Parameter(property = "javacpp.properties")
    String properties = null;

    /** Load all properties from file. */
    @Parameter(property = "javacpp.propertyFile")
    File propertyFile = null;

    /** Set property keys to values. */
    @Parameter(property = "javacpp.propertyKeysAndValues")
    Properties propertyKeysAndValues = null;

    /** Process only this class or package (suffixed with .* or .**). */
    @Parameter(property = "javacpp.classOrPackageName")
    String classOrPackageName = null;

    /** Process only these classes or packages (suffixed with .* or .**). */
    @Parameter(property = "javacpp.classOrPackageNames")
    String[] classOrPackageNames = null;

    /** Add environment variables to the compiler subprocess. */
    @Parameter(property = "javacpp.environmentVariables")
    Map<String, String> environmentVariables = null;

    /** Pass compilerOptions directly to compiler. */
    @Parameter(property = "javacpp.compilerOptions")
    String[] compilerOptions = null;

    /** Skip the execution. */
    @Parameter(property = "javacpp.skip", defaultValue = "false")
    boolean skip = false;

    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    MavenProject project;

    String[] merge(String[] ss, String s) {
        if (ss != null && s != null) {
            ss = Arrays.copyOf(ss, ss.length + 1);
            ss[ss.length - 1] = s;
        } else if (s != null) {
            ss = new String[] { s };
        }
        return ss != null ? ss : new String[0];
    }

    @Override
    public void execute() throws MojoExecutionException {
        final Log log = getLog();
        try {
            if (log.isDebugEnabled()) {
                log.debug("classPath: " + classPath);
                log.debug("classPaths: " + Arrays.deepToString(classPaths));
                log.debug("includePath: " + includePath);
                log.debug("includePaths: " + Arrays.deepToString(includePaths));
                log.debug("linkPath: " + linkPath);
                log.debug("linkPaths: " + Arrays.deepToString(linkPaths));
                log.debug("preloadPath: " + preloadPath);
                log.debug("preloadPaths: " + Arrays.deepToString(preloadPaths));
                log.debug("outputDirectory: " + outputDirectory);
                log.debug("outputName: " + outputName);
                log.debug("compile: " + compile);
                log.debug("deleteJniFiles: " + deleteJniFiles);
                log.debug("header: " + header);
                log.debug("copyLibs: " + copyLibs);
                log.debug("jarPrefix: " + jarPrefix);
                log.debug("properties: " + properties);
                log.debug("propertyFile: " + propertyFile);
                log.debug("propertyKeysAndValues: " + propertyKeysAndValues);
                log.debug("classOrPackageName: " + classOrPackageName);
                log.debug("classOrPackageNames: " + Arrays.deepToString(classOrPackageNames));
                log.debug("environmentVariables: " + environmentVariables);
                log.debug("compilerOptions: " + Arrays.deepToString(compilerOptions));
                log.debug("skip: " + skip);
            }

            if (skip) {
                log.info("Skipping execution of JavaCPP Builder");
                return;
            }

            classPaths = merge(classPaths, classPath);
            classOrPackageNames = merge(classOrPackageNames, classOrPackageName);

            Logger logger = new Logger() {
                @Override
                public void debug(String s) {
                    log.debug(s);
                }

                @Override
                public void info(String s) {
                    log.info(s);
                }

                @Override
                public void warn(String s) {
                    log.warn(s);
                }

                @Override
                public void error(String s) {
                    log.error(s);
                }
            };
            Builder builder = new Builder(logger).classPaths(classPaths).outputDirectory(outputDirectory)
                    .outputName(outputName).compile(compile).deleteJniFiles(deleteJniFiles).header(header)
                    .copyLibs(copyLibs).jarPrefix(jarPrefix).properties(properties).propertyFile(propertyFile)
                    .properties(propertyKeysAndValues).classesOrPackages(classOrPackageNames)
                    .environmentVariables(environmentVariables).compilerOptions(compilerOptions);
            Properties properties = builder.properties;
            log.info("Detected platform \"" + Loader.getPlatform() + "\"");
            log.info("Building for platform \"" + properties.get("platform") + "\"");
            String separator = properties.getProperty("platform.path.separator");
            for (String s : merge(includePaths, includePath)) {
                String v = properties.getProperty("platform.includepath", "");
                properties.setProperty("platform.includepath",
                        v.length() == 0 || v.endsWith(separator) ? v + s : v + separator + s);
            }
            for (String s : merge(linkPaths, linkPath)) {
                String v = properties.getProperty("platform.linkpath", "");
                properties.setProperty("platform.linkpath",
                        v.length() == 0 || v.endsWith(separator) ? v + s : v + separator + s);
            }
            for (String s : merge(preloadPaths, preloadPath)) {
                String v = properties.getProperty("platform.preloadpath", "");
                properties.setProperty("platform.preloadpath",
                        v.length() == 0 || v.endsWith(separator) ? v + s : v + separator + s);
            }
            Properties projectProperties = project.getProperties();
            for (String key : properties.stringPropertyNames()) {
                projectProperties.setProperty("javacpp." + key, properties.getProperty(key));
            }
            File[] outputFiles = builder.build();
            if (log.isDebugEnabled()) {
                log.debug("outputFiles: " + Arrays.deepToString(outputFiles));
            }
        } catch (IOException | ClassNotFoundException | NoClassDefFoundError | InterruptedException
                | ParserException e) {
            log.error("Failed to execute JavaCPP Builder: " + e.getMessage());
            throw new MojoExecutionException("Failed to execute JavaCPP Builder", e);
        }
    }
}