All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bytedeco.gradle.javacpp.BuildPlugin Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2020-2022 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.gradle.javacpp;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Properties;
import java.util.Set;
import org.bytedeco.javacpp.Loader;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.Plugin;
import org.gradle.api.Task;
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.provider.Property;
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.WriteProperties;
import org.gradle.api.tasks.bundling.Jar;
import org.gradle.api.tasks.compile.JavaCompile;

/**
 * This plugin creates new packages containing native libraries using JavaCPP.
 * It defines the following extra property:
 * 

    *
  • "javacppPlatform", which defaults to {@link Loader#getPlatform()}, *
  • "javacppPlatformExtension", which defaults to an empty string, *

* * creates the following extension: *

    *
  • "javacppBuild", an instance of {@link BuildExtension}, *

* * as well as the following configuration: *

    *
  • "javacppPlatform", to be used to specify dependencies for the "-platform" artifact, *

* * and registers the following tasks: *

    *
  • "javacppBuildCommand" to execute {@link BuildTask#buildCommand}, *
  • "javacppCompileJava" to compile classes needed by the parser, *
  • "javacppBuildParser" to run the parser on these classes, *
  • "javacppBuildCompiler" to generate and compile JNI code, *
  • "javacppPomProperties" to write version information to pom.properties, *
  • "javacppJar" to archive the native libraries in a separate JAR file, *
  • "javacppPlatformJar", to create an empty JAR file for the main "-platform" artifact, *
  • "javacppPlatformJavadocJar", to create an empty JAR file for the "-platform" javadoc artifact, and *
  • "javacppPlatformSourcesJar", to create an empty JAR file for the "-platform" sources artifact, *

* * @author Samuel Audet */ public class BuildPlugin implements Plugin { Project project; String getPlatform() { return (String)project.findProperty("javacppPlatform"); } String getPlatformExtension() { return (String)project.findProperty("javacppPlatformExtension"); } boolean isLibraryPath(String path) { String p = (String)project.findProperty("javacpp.platform.library.path"); return p != null && p.length() > 0 ? path.startsWith(p) : path.contains("/" + getPlatform() + getPlatformExtension() + "/"); } private void setProperty(String originalMethod, String propertyField, Object target, T value) { Method method = findMethod(target.getClass(), originalMethod, value.getClass()); if (method != null) { try { invoke(method, target, value); } catch (Exception e) { throw new RuntimeException("Cannot set property " + method.getName() + " in " + target.getClass(), e); } } else { Method propertyGetter = findMethod(target.getClass(), propertyField); if (propertyGetter == null) { throw new RuntimeException("Cannot find property getter method " + propertyField + " in " + target.getClass()); } ((Property) invoke(propertyGetter, target)).set(value); } } private T getProperty(String originalMethod, String propertyMethod, Object target) { Method method = findMethod(target.getClass(), originalMethod); if (method != null) { return (T) invoke(method, target); } Method propertyGetter = findMethod(target.getClass(), propertyMethod); if (propertyGetter == null) { throw new RuntimeException("Cannot find property getter method " + propertyMethod + " in " + target.getClass()); } return ((Property) invoke(propertyGetter, target)).get(); } private Method findMethod(Class cls, String methodName) { for (Method method : cls.getMethods()) { if (method.getName().equals(methodName)) { return method; } } return null; } private Method findMethod(Class cls, String methodName, Class... parameterTypes) { try { return cls.getMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { return null; } } private T invoke(Method method, Object target, Object... parameter) { try { return (T) method.invoke(target, parameter); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } @Override public void apply(final Project project) { this.project = project; if (!project.hasProperty("javacppPlatform")) { project.getExtensions().getExtraProperties().set("javacppPlatform", Loader.Detector.getPlatform()); } if (!project.hasProperty("javacppPlatformExtension")) { project.getExtensions().getExtraProperties().set("javacppPlatformExtension", ""); } if (project.getExtensions().findByName("javacppBuild") == null) { project.getExtensions().create("javacppBuild", BuildExtension.class, this); } project.getPlugins().withType(JavaPlugin.class, new Action() { public void execute(JavaPlugin javaPlugin) { final JavaPluginConvention jc = project.getConvention().getPlugin(JavaPluginConvention.class); final SourceSet main = jc.getSourceSets().getByName("main"); final Set files = main.getOutput().getClassesDirs().getFiles(); final String[] paths = new String[files.size()]; int n = 0; for (File file : files) { try { paths[n++] = file.getCanonicalPath(); } catch (IOException ex) { paths[n++] = file.getAbsolutePath(); } } project.getTasks().register("javacppBuildCommand", BuildTask.class, new Action() { public void execute(BuildTask task) { task.classPath = paths; task.properties = getPlatform(); if (getPlatformExtension() != null && getPlatformExtension().length() > 0) { task.propertyKeysAndValues = new Properties(); task.propertyKeysAndValues.setProperty("platform.extension", getPlatformExtension()); } task.classOrPackageNames = new String[0]; task.workingDirectory = project.getProjectDir(); }}); project.getTasks().register("javacppCompileJava", JavaCompile.class, new Action() { public void execute(JavaCompile task) { task.setSource(main.getJava()); task.setClasspath(main.getCompileClasspath()); setProperty( "setDestinationDir", // Deprecated in 7.1, will be removed in Gradle 9.0 "getDestinationDirectory", // Since 6.1 task, getProperty( "getOutputDir", // Deprecated in 7.1, removed in Gradle 8.0 "getClassesDirectory", // Since 6.1 main.getJava() ) ); task.dependsOn("javacppBuildCommand"); }}); project.getTasks().register("javacppBuildParser", BuildTask.class, new Action() { public void execute(final BuildTask task) { task.classPath = paths; task.properties = getPlatform(); if (getPlatformExtension() != null && getPlatformExtension().length() > 0) { task.propertyKeysAndValues = new Properties(); task.propertyKeysAndValues.setProperty("platform.extension", getPlatformExtension()); } if (task.outputDirectory == null) { task.outputDirectory = main.getJava().getSrcDirs().iterator().next(); } task.dependsOn("javacppCompileJava"); task.doFirst(new Action() { public void execute(Task t) { main.getJava().srcDir(task.outputDirectory); }}); }}); project.getTasks().getByName("compileJava").dependsOn("javacppBuildParser"); project.getTasks().register("javacppBuildCompiler", BuildTask.class, new Action() { public void execute(BuildTask task) { task.classPath = paths; task.properties = getPlatform(); if (getPlatformExtension() != null && getPlatformExtension().length() > 0) { task.propertyKeysAndValues = new Properties(); task.propertyKeysAndValues.setProperty("platform.extension", getPlatformExtension()); } task.dependsOn("compileJava"); }}); project.getTasks().getByName("classes").dependsOn("javacppBuildCompiler"); project.getTasks().register("javacppPomProperties", WriteProperties.class, new Action() { public void execute(WriteProperties task) { Object group = project.findProperty("group"); Object name = project.findProperty("name"); Object version = project.findProperty("version"); task.property("groupId", group); task.property("artifactId", name); task.property("version", version); task.setOutputFile(new File(main.getOutput().getResourcesDir(), "META-INF/maven/" + group + "/" + name + "/pom.properties")); }}); Jar jarTask = (Jar)project.getTasks().getByName("jar"); jarTask.dependsOn("javacppPomProperties"); jarTask.exclude(new Spec() { public boolean isSatisfiedBy(FileTreeElement file) { return isLibraryPath(file.getPath()); }}); TaskProvider javacppJarTask = project.getTasks().register("javacppJar", Jar.class, new Action() { public void execute(Jar task) { task.from(main.getOutput()); setProperty( "setClassifier", // Deprecated in 7.0, removed in 8.0 "getArchiveClassifier", // Since 5.1 task, getPlatform() + getPlatformExtension()); task.include(new Spec() { public boolean isSatisfiedBy(FileTreeElement file) { return file.isDirectory() || isLibraryPath(file.getPath()); }}); task.dependsOn("jar"); }}); project.getArtifacts().add("archives", javacppJarTask); TaskProvider javacppPlatformJarTask = project.getTasks().register("javacppPlatformJar", Jar.class, new Action() { public void execute(Jar task) { setProperty( "setBaseName", // Deprecated in 7.0, removed in 8.0 "getArchiveBaseName", // Since 5.1 task, project.getName() + "-platform"); task.dependsOn("javacppJar"); }}); TaskProvider javacppPlatformJavadocJarTask = project.getTasks().register("javacppPlatformJavadocJar", Jar.class, new Action() { public void execute(Jar task) { setProperty( "setBaseName", // Deprecated in 7.0, removed in 8.0 "getArchiveBaseName", // Since 5.1 task, project.getName() + "-platform"); setProperty( "setClassifier", // Deprecated in 7.0, removed in 8.0 "getArchiveClassifier", // Since 5.1 task, "javadoc"); task.dependsOn("javacppPlatformJar"); }}); TaskProvider javacppPlatformSourcesTask = project.getTasks().register("javacppPlatformSourcesJar", Jar.class, new Action() { public void execute(Jar task) { setProperty( "setBaseName", // Deprecated in 7.0, removed in 8.0 "getArchiveBaseName", // Since 5.1 task, project.getName() + "-platform"); setProperty("setClassifier", "getArchiveClassifier", task, "sources"); task.dependsOn("javacppPlatformJar"); }}); project.getConfigurations().maybeCreate("javacppPlatform"); project.getArtifacts().add("javacppPlatform", javacppPlatformJarTask); project.getArtifacts().add("javacppPlatform", javacppPlatformJavadocJarTask); project.getArtifacts().add("javacppPlatform", javacppPlatformSourcesTask); }}); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy