Java tutorial
/* * 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); } } }