Coder Social home page Coder Social logo

bytedeco / gradle-javacpp Goto Github PK

View Code? Open in Web Editor NEW
56.0 6.0 19.0 86 KB

Gradle plugins to automate the build process of JavaCPP and JavaCV

License: Other

Java 100.00%
gradle gradle-plugin javacpp java c cpp c-plus-plus jni javacv opencv opencv-java

gradle-javacpp's Introduction

Gradle JavaCPP

Gitter Maven Central Sonatype Nexus (Snapshots) Build Status Commercial support: xscode

Introduction

Gradle JavaCPP offers plugins that make it easy to use JavaCPP and JavaCV as part of the Gradle build system.

Please feel free to ask questions on the mailing list if you encounter any problems with the software! I am sure it is far from perfect...

Required Software

To use Gradle JavaCPP, you will need to download and install the following software:

Getting Started

Gradle JavaCPP comes with 2 plugins:

  • The build plugin to create new packages containing native libraries using JavaCPP, and
  • The platform plugin to select from existing artifacts the ones corresponding to user-specified platforms.

Fully functional sample projects are also provided in the samples subdirectory and can be used as templates.

The Build Plugin

To understand how JavaCPP is meant to be used, one should first take a look at the Mapping Recipes for C/C++ Libraries, but a high-level overview of the Basic Architecture is also available to understand the bigger picture.

Once comfortable enough with the command line interface, the build plugin for Gradle can be used to integrate easily that workflow as part of build.gradle as shown below. By default, for Java libraries and applications, it creates a javacppJar task that archives the native libraries into a separate JAR file and sets its classifier to $javacppPlatform$javacppPlatformExtension, while excluding those files from the default jar task. To customize the behavior, there are properties that can be modified and whose documentation is available as part of the source code in these files:

plugins {
    id 'java-library'
    id 'org.bytedeco.gradle-javacpp-build' version "$javacppVersion"
}

// We can set this on the command line too this way: -PjavacppPlatform=android-arm64
ext {
    javacppPlatform = 'android-arm64' // or any other platform, defaults to Loader.getPlatform()
}

dependencies {
    api "org.bytedeco:javacpp:$javacppVersion"
}

tasks.withType(org.bytedeco.gradle.javacpp.BuildTask) {
    // set here default values for all build tasks below, typically just includePath and linkPath,
    // but also properties to set the path to the NDK and its compiler in the case of Android
}

javacppBuildCommand {
    // typically set here the buildCommand to the script that fills up includePath and linkPath
}

javacppBuildParser {
    // typically set here the classOrPackageNames to class names implementing InfoMap
}

javacppBuildCompiler {
    // typically set here boolean flags like copyLibs
}

Integration with Android Studio

It is also possible to integrate the BuildTask with Android Studio for projects with C/C++ support by:

  1. Following the instructions at https://developer.android.com/studio/projects/add-native-code ,
  2. Adding something like below to the app/build.gradle file, and
android.applicationVariants.all { variant ->
    def variantName = variant.name.capitalize() // either "Debug" or "Release"
    def javaCompile = project.tasks.getByName("compile${variantName}JavaWithJavac")
    def configureCMake = project.tasks.findAll {
        it.name.startsWith("configureCMake$variantName")
    }

    // Compiles NativeLibraryConfig.java
    task "javacppCompileJava$variantName"(type: JavaCompile) {
        include 'com/example/myapplication/NativeLibraryConfig.java'
        source = javaCompile.source
        classpath = javaCompile.classpath
        destinationDir = javaCompile.destinationDir
    }

    // Parses NativeLibrary.h and outputs NativeLibrary.java
    task "javacppBuildParser$variantName"(type: org.bytedeco.gradle.javacpp.BuildTask) {
        dependsOn "javacppCompileJava$variantName"
        classPath = [javaCompile.destinationDir]
        includePath =  ["$projectDir/src/main/cpp/"]
        classOrPackageNames = ['com.example.myapplication.NativeLibraryConfig']
        outputDirectory = file("$projectDir/src/main/java/")
    }

    // Compiles NativeLibrary.java and everything else
    javaCompile.dependsOn "javacppBuildParser$variantName"

    // Generates jnijavacpp.cpp and jniNativeLibrary.cpp
    task "javacppBuildCompiler$variantName"(type: org.bytedeco.gradle.javacpp.BuildTask) {
        dependsOn javaCompile
        classPath = [javaCompile.destinationDir]
        classOrPackageNames = ['com.example.myapplication.NativeLibrary']
        compile = false
        deleteJniFiles = false
        outputDirectory = file("$projectDir/src/main/cpp/")
    }

    // Picks up the C++ files listed in CMakeLists.txt
    configureCMake.forEach {
        it.dependsOn "javacppBuildCompiler$variantName"
    }
}
  1. Updating the CMakeLists.txt file to include the generated .cpp files.

The Platform Plugin

With Maven, we are able to modify dependencies transitively using profiles, and although Gradle doesn't provide such functionality out of the box, it can be emulated via plugins. After adding a single line to the build.gradle script as shown below, the platform plugin will filter the dependencies of artifacts whose names contain "-platform" using the comma-separated values given in $javacppPlatform. To understand better how this works, it may be worth taking a look at the source code of the plugin:

plugins {
    id 'java-library'
    id 'org.bytedeco.gradle-javacpp-platform' version "$javacppVersion"
}

// We can set this on the command line too this way: -PjavacppPlatform=linux-x86_64,macosx-x86_64,windows-x86_64,etc
ext {
    javacppPlatform = 'linux-x86_64,macosx-x86_64,windows-x86_64,etc' // defaults to Loader.getPlatform()
}

dependencies {
    api "org.bytedeco:javacv-platform:$javacvVersion" // or any other "-platform" artifacts
}

Moreover, in the case of Android, its plugin is not able to use native libraries found in JAR files when building Android App Bundles (AAB files). However, to work around this limitation we can easily use Gradle to extract the files automatically, for example, in the following manner with an additional javacppExtract task inside app/build.gradle:

configurations {
    javacpp
}

task javacppExtract(type: Copy) {
    dependsOn configurations.javacpp

    from { configurations.javacpp.collect { zipTree(it) } }
    include "lib/**"
    into "$buildDir/javacpp/"
    android.sourceSets.main.jniLibs.srcDirs += ["$buildDir/javacpp/lib/"]

    tasks.getByName('preBuild').dependsOn javacppExtract
}

dependencies {
    implementation group: 'org.bytedeco', name: 'javacv', version: "$javacvVersion"
    javacpp group: 'org.bytedeco', name: 'openblas-platform', version: "$openblasVersion-$javacppVersion"
    javacpp group: 'org.bytedeco', name: 'opencv-platform', version: "$opencvVersion-$javacppVersion"
    javacpp group: 'org.bytedeco', name: 'ffmpeg-platform', version: "$ffmpegVersion-$javacppVersion"
    ...
}

Project lead: Samuel Audet samuel.audet at gmail.com
Developer site: https://github.com/bytedeco/gradle-javacpp
Discussion group: http://groups.google.com/group/javacpp-project

gradle-javacpp's People

Contributors

devjeonghwan avatar equeim avatar junlarsen avatar milkyway0308 avatar saudet avatar sleshjdev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gradle-javacpp's Issues

Not possible to build with newer Gradle

Trying with latest Gradle...

javacppBuildCommand {
	// typically set here the buildCommand to the script that fills up includePath and linkPath
}

javacppBuildParser {
	// typically set here the classOrPackageNames to class names implementing InfoMap
}

javacppBuildCompiler {
	// typically set here boolean flags like copyLibs
}

tasks.withType(org.bytedeco.gradle.javacpp.BuildTask) {
	// set here default values for all build tasks below, typically just includePath and linkPath,
	// but also properties to set the path to the NDK and its compiler in the case of Android
	generate = true;
	compile = false;
	outputDirectory = new File("src/main/cpp");
}

Result:

> Task :javacppBuildParser FAILED
Execution optimizations have been disabled for task ':javacppBuildParser' to ensure correctness due to the following reasons:
  - Additional action of task ':javacppBuildParser' was implemented by the Java lambda 'org.bytedeco.gradle.javacpp.BuildPlugin$$Lambda$814/0x00000008012f1af0'. Reason: Using Java lambdas is not supported as task inputs. Please refer to https://docs.gradle.org/7.4/userguide/validation_problems.html#implementation_unknown for more details about this problem.

Execution failed for task ':javacppBuildParser'.
> net/fabricmc/api/ModInitializer

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

Can't configure BuildTask from Kotlin DSL, methods and fields are package-private

If I try to register BuildTask in build.gradle.kts like that:

tasks.register<BuildTask>("javacppParse$variantName") {
    dependsOn(javacppCompileConfig)
    setClassPath(arrayOf(javaCompile.destinationDir.toString()))
}

Then I will have this error:

Script compilation error:

  Line 103:         setClassPath(arrayOf(javaCompile.destinationDir.toString()))
                    ^ Cannot access 'setClassPath': it is package-private in 'BuildTask'

I have a problem with generating ./gradlew from gradle wrapper in the samples/zlib

Hi,
I have a problem with generating ./gradlew from gradle wrapper.

installed gradle: 4.4.1

compile sample:
https://github.com/bytedeco/gradle-javacpp/tree/master/samples/zlib

error info:
root@ubuntu:/home/jni/gradle-javacpp/samples/zlib# gradle wrapper
Starting a Gradle Daemon (subsequent builds will be faster)

FAILURE: Build failed with an exception.

  • What went wrong:
    'org.gradle.api.tasks.TaskProvider org.gradle.api.tasks.TaskContainer.register(java.lang.String, java.lang.Class, org.gradle.api.Action)'

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 10s

getOriginalMetadata() missing in Gradle 7.6

I've found this extremely useful, but upgrading to Gradle 7.6 today resulted in a large number of messages

Could not get the classifier of org.bytedeco:javacpp:1.5.8: java.lang.NoSuchMethodException: org.gradle.api.internal.artifacts.repositories.resolver.AbstractDependencyMetadataAdapter.getOriginalMetadata()

and jars for all the platforms being downloaded.

As far as I can tell, the problem is that AbstractDependencyMetadataAdapter.getOriginalMetadata() was removed in this commit: gradle/gradle@ad1cc1c

The good news (I hope) is that there's now a public AbstractDependencyMetadataAdapter.getMetadata().

Caused by: java.lang.NoClassDefFoundError: com/package/MyInterface wrong name: API/build/classes/java/main/com/package/MyInterface

I am attempting to generate JNI code inside a gradle multi-project build.

The directory structure is as follows:

/JavaCpp
-> /API
-> /Impl

The /Impl subproject contains the cpp header files and JavaCpp annotations required for generating the JNI .so library. It also contains two Java files MyClass.java and Delegate.java.

Inside the Impl subproject:

public class MyClass implements MyInterface {
    private final Delegate delegate;

    @Override
    public boolean function() {
        return delegate.function()
    }

@Platform(include = "/lib/process.h", link="process")
public class Delegate {

    @Function()
    public native boolean function();

The API subproject contains a Java interface that describes the functions the JNI code implements.

Inside the API subproject:
public interface MyInterface  {
    boolean function();

During the :Impl:javacppBuildParser task, I'm getting the following error:

Execution failed for task ':Impl:javacppBuildParser'.
#18 21.53 > com/package/MyInterface (wrong name: API/build/classes/java/main/com/package/MyInterface)

Is there some way I can prevent this class from being scanned by JavaCpp? It is not needed during the JavaCpp building since all of the JavaCpp annotations are being applied to the Delegate class.

Is there kotlin dsl support?

I tried to use the plugin with kotlin dsl but it doesn't like to work. I get errors like this:

$ ../../gradlew check

FAILURE: Build failed with an exception.

* Where:
Build file '/tmp/gradle-javacpp/samples/javacv-demo-kotlindsl/build.gradle.kts' line: 7

* What went wrong:
Plugin [id: 'org.bytedeco.gradle-javacpp-platform', version: '1.5.4-SNAPSHOT'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'org.bytedeco.gradle-javacpp-platform:org.bytedeco.gradle-javacpp-platform.gradle.plugin:1.5.4-SNAPSHOT')
  Searched in the following repositories:
    Gradle Central Plugin Repository

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Everything works fine with groovy. Any ideas?

How to use javacv and ffmpeg-platform on Android ? (error: libjniavutil.so not found)

I am trying to use this plugin in Android gradle. my gradle code is as follows:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
    id 'org.bytedeco.gradle-javacpp-platform' version "1.5.9"
}

android {
   ....
}

configurations {
    javacpp
}

task javacppExtract(type: Copy) {
    dependsOn configurations.javacpp

    from { configurations.javacpp.collect { zipTree(it) } }
    include "lib/**"
    into "$buildDir/javacpp/"
    android.sourceSets.main.jniLibs.srcDirs += ["$buildDir/javacpp/lib/"]

    tasks.getByName('preBuild').dependsOn javacppExtract
}

dependencies {
    ......

    def javacppVersion = '1.5.9'
    def ffmpegVersion = '6.0'
    implementation group: 'org.bytedeco', name: 'javacv', version: "$javacppVersion"
    javacpp group: 'org.bytedeco', name: 'ffmpeg-platform', version: "$ffmpegVersion-$javacppVersion"
}

I build the project successfully but when i reach the FFmpeg code which is like this (I think the code does not matter):

// Open the MP3 file
val formatContext = AVFormatContext(null)
if (avformat.avformat_open_input(formatContext, mp3FilePath, null, null) != 0) {
      println("Could not open the input file")
      return
} 
...
....

And this gives the following runtime error :

java.lang.UnsatisfiedLinkError: dlopen failed: library "libjniavutil.so" not found
     at java.lang.Runtime.loadLibrary0(Runtime.java:1077)
      at java.lang.Runtime.loadLibrary0(Runtime.java:998)
    at java.lang.System.loadLibrary(System.java:1661)
    at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1832)
    at org.bytedeco.javacpp.Loader.load(Loader.java:1423)
    at org.bytedeco.javacpp.Loader.load(Loader.java:1234)
    at org.bytedeco.javacpp.Loader.load(Loader.java:1210)
    at org.bytedeco.ffmpeg.global.avutil.<clinit>(avutil.java:14)
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:454)
    at org.bytedeco.javacpp.Loader.load(Loader.java:1289)
   at org.bytedeco.javacpp.Loader.load(Loader.java:1234)
    at org.bytedeco.javacpp.Loader.load(Loader.java:1210)
    at org.bytedeco.ffmpeg.avformat.AVFormatContext.<clinit>(AVFormatContext.java:36)

Can not generate jnijavacpp.cpp and jniNativeLibrary.cpp

I am refrencing gradle-javacpp-android to use javacpp with android studio. After a bit adjust to gradle-javacpp-android, it successfully generated NativeLibrary. But jnijavacpp.cpp and jniNativeLibrary.cpp are not generated.

plugins {
    id 'com.android.application'
    id 'org.bytedeco.gradle-javacpp-build' version '1.5.7'
}

allprojects {
    tasks.withType(JavaCompile) {
        options.compilerArgs << "-Xlint:unchecked"
    }
}

android {
    compileSdkVersion 32

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 28
        targetSdkVersion 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.18.1"
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    ndkVersion '25.1.8937393'
    buildToolsVersion '33.0.0'
}

android.applicationVariants.all { variant ->
    def variantName = variant.name.capitalize() // either "Debug" or "Release"
    def javaCompile = project.tasks.getByName("compile${variantName}JavaWithJavac")
    def generateJson = project.tasks.getByName("generateJsonModel$variantName")

    // Compiles NativeLibraryConfig.java
    task "javacppCompileJava$variantName"(type: JavaCompile) {
        include 'com/example/myapplication/NativeLibraryConfig.java'
        source = javaCompile.source
        classpath = javaCompile.classpath
        destinationDir = javaCompile.destinationDir
        doLast{
            println "Hello World javacppCompileJava"
        }
    }

    // Parses NativeLibrary.h and outputs NativeLibrary.java
    task "javacppBuildParser$variantName"(type: org.bytedeco.gradle.javacpp.BuildTask) {
        dependsOn "javacppCompileJava$variantName"
        classPath = [javaCompile.destinationDir]
        includePath =  ["$projectDir/src/main/cpp/"]
        classOrPackageNames = ['com.example.myapplication.NativeLibraryConfig']
        outputDirectory = file("$projectDir/src/main/java/")
        doLast{
            println "Hello World javacppBuildParser"
        }
    }

    // Compiles NativeLibrary.java and everything else
    javaCompile.dependsOn "javacppBuildParser$variantName"

    // Generates jnijavacpp.cpp and jniNativeLibrary.cpp
    task "javacppBuildCompiler$variantName"(type: org.bytedeco.gradle.javacpp.BuildTask) {
        dependsOn javaCompile
        classPath = [javaCompile.destinationDir]
        classOrPackageNames = ['com.example.myapplication.NativeLibrary']
        compile = true
        deleteJniFiles = false
        outputDirectory = file("$projectDir/src/main/cpp/")
        doLast{
            println "Hello World javacppBuildCompiler"
        }
    }

    // Picks up the C++ files listed in CMakeLists.txt
    generateJson.dependsOn "javacppBuildCompiler$variantName"
}

dependencies {

    implementation 'org.bytedeco:javacpp:1.5.7'
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.7.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

javacppPlatform property is ignored

It appears that the javacppPlatform property is ignored. No matter what I write, all I get is the linux-x86_64 libs (when I really want arm libs, too)

plugins {
    id "org.jetbrains.kotlin.jvm" version "1.4.10"
    id "application"
    id 'org.bytedeco.gradle-javacpp-platform' version "1.5.4"
}

ext {
    javacppPlatform = 'linux-arm'
}

group "rover"
version "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

mainClassName = "MainKt"

dependencies {
    testImplementation group: "junit", name: "junit", version: "4.12"
    compile "org.jetbrains.kotlin:kotlin-stdlib"
    compile group: "com.pi4j", name: "pi4j-gpio-extension", version: "1.2"
    compile group: "org.bytedeco", name: "javacv", version: "1.5.4"
    compile 'org.bytedeco:opencv-platform:4.4.0-1.5.4'
}

How can I choose specified module such as only ffmpeg

This project idea is great, very good make up for the deficiency of the gradle,

import all javacpp library is so big for me, so I want choose specified module, some thing like that
image

thise module already satisfy for me, how can I use javacppPlatform like that?

Skipping cppbuild with Build plugin

Is there any way to prevent the BuildTask.buildCommand from running either programatically or through the environment? Sorts of like the property javacpp.cppbuild.skip for the Maven builds?

I tried to enable BuildTask.skip but it does not look like the plugin respects this option. As far as I can tell, the BuildPlugin doesn't ever use the property anyways so it's just hanging there, unused.

Assuming that BuildTask.skip is the equivalent of the aforementioned cppbuild.skip, I have submitted a patch to junlarsen@f2653dc which I can PR in.

SourceDirectorySet.getOutputDir() has been removed in gradle >= 8

Hi,
with gradle 8.x, loading the plugin version 1.5.9 fails with

  • What went wrong:
    An exception occurred applying plugin request [id: 'org.bytedeco.gradle-javacpp-build', version: '1.5.9']

Failed to apply plugin 'org.bytedeco.gradle-javacpp-build'.
Could not create task ':cavis-native:cavis-native-lib:javacppCompileJava'.
> 'java.io.File org.gradle.api.file.SourceDirectorySet.getOutputDir()'

The reason is, that getOutputDir() has been replaced with getClassesDirectory
gradle/gradle@aeb4e00#diff-e6ac06306676ba80c5ed481c54208dfb7cf3ade725900705537fa38a3ee426f9

Stacktrace:

Caused by: org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreationException: Could not create task ':cavis-native:cavis-native-lib:javacppCompileJava'.
at org.gradle.api.internal.tasks.DefaultTaskContainer.taskCreationException(DefaultTaskContainer.java:721)
at org.gradle.api.internal.tasks.DefaultTaskContainer.access$600(DefaultTaskContainer.java:77)
at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.domainObjectCreationException(DefaultTaskContainer.java:713)
at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.tryCreate(DefaultNamedDomainObjectCollection.java:948)
at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.access$1401(DefaultTaskContainer.java:660)
at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider$1.run(DefaultTaskContainer.java:686)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.tryCreate(DefaultTaskContainer.java:682)
at ...snipp...

Caused by: java.lang.NoSuchMethodError: 'java.io.File org.gradle.api.file.SourceDirectorySet.getOutputDir()'
at org.bytedeco.gradle.javacpp.BuildPlugin$1$2.execute(BuildPlugin.java:134) <----- HERE
at org.bytedeco.gradle.javacpp.BuildPlugin$1$2.execute(BuildPlugin.java:131)
at org.gradle.api.internal.DefaultMutationGuard$1.execute(DefaultMutationGuard.java:45)
at org.gradle.api.internal.DefaultMutationGuard$1.execute(DefaultMutationGuard.java:45)
at ...snipp...

caching not working when using buildCommand only

Hi,

I am trying to use the plugin to execute an arbitrary shell command and leverage its caching function.

plugins {
    id 'java-library'
    id 'org.bytedeco.gradle-javacpp-build' version "1.5.5"
}
javacppBuildCommand {
   buildCommand = ['sh', 'something.sh']
}

Issues:

  1. How to achieve, that dependencies are downloaded and extracted into the javacpp cache folder?
    I tried to include dependencies as api, implementation and javacppPlatform without luck. Also referencing included classes as linkResources, includeResources or buildResource, did not make the difference.

  2. How to pass environment variables set by the javacpp Builder to either the shell script called or have them set in the system environment? I.e. Builder is setting BUILD_DIR, that does not come through?

Thanks
Brian

Properly get string from a char * using BytePointer?

Hi

I try to fetch a "String" from a C function with char * signature, using BytePointer in JavaCPP.
However when I call the getString method, it returns the string with length of allocated size, instead of using the '\0' position.

scala code below:

    val deviceName = new BytePointer(1000L)
    deviceName.fill(0)
    cuDeviceGetName(deviceName, 1000, device.get())
    println("device name: " + deviceName.getString("utf-8"))

    println("str len: ", deviceName.getString("utf-8").length)

You'll find the last line prints out

(str len: ,1000)

Gradle Multi-module support

In an effort to separate our main business logic from javacpp, I've setup our project using gradle's multi-module support with a structure like so

src/
   business-logic/ # rest controllers and other business logic that call the interface
   javacpp-interface/ # Single class with interface methods
   javacpp-implementation # implements the interface

Both the business-logic and javacpp-implementation modules have a dependency on javacpp-interface. This will allow us to write unit tests in the business-logic layer without relying on javacpp code(We develop on windows but the C++ library is targeting linux in a docker image).

What I'm running into issues with is that the implementation class fails to compile as it cannot see the interface class in the javacpp-interface. We end up receiving class loader issues like such:

[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Execution failed for task ':javacpp-implementation:javacppBuildParser'.
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > com/my-org/ndi/javacpp/impl/INativeNdiService
Unable to load class 'com.my-org.ndi.javacpp.impl.INativeNdiService'.

Both the interface and the implementation are in the same package structure, but different modules.

My gradle file looks something like this(Note we are using the latest version 1.5.8 that's stored in a gradle catalog):

plugins {
    id 'java-library'

    alias(libs.plugins.bytedeco.javacpp.build)
    alias(libs.plugins.bytedeco.javacpp.platform)
    alias(libs.plugins.springboot)
    alias(libs.plugins.dependencyManagement)
}

javacppCompileJava {
    include 'com/my-org/ndi/javacpp/impl/*'
} 

dependencies {
    implementation project(":javacpp-interface")
    implementation libs.bytedeco
}

How can I change javacppPlatform at runtime?

I want use macosx-x86_64 on run application, but use linux-x86_64 when package.

These way seems not working.

    parent?.ext?.set("javacppPlatform", "linux-x86_64")
    println(parent?.ext?.get("javacppPlatform"))
    implementation(group = "org.bytedeco", name = "javacpp")
    implementation(group = "org.bytedeco", name = "ffmpeg-platform")
    implementation(group = "org.bytedeco", name = "javacv")

or

tasks {
    "war"(War::class) {
        first {
            parent?.ext?.set("javacppPlatform", "linux-x86_64")
            println(parent?.ext?.get("javacppPlatform"))
            true
        }
        enabled = true
    }
}

task javacppCompileJava fails with lombok

Hi,

gradle fails to build java code, when the gradle-javacpp plugin is added. It looks liek javacppCompileJava is not working correctly.

Example gradle.build

plugins {
id 'java-library'
id 'org.bytedeco.gradle-javacpp-build' version "1.5.5"
}

dependencies {
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
}

Example java code like:

import lombok.val;

public class Bla {
void example() {
val something = somedatatype;
}
}

Error message during gradle build:
example:
error: incompatible types: org.nd4j.linalg.api.ndarray.INDArray cannot be converted to lombok.val
val fA = A.castTo(DataType.FLOAT);

The problem goes away, when the gradle-javacpp plugin is removed from gradle.build

Thanks
Brian

Android example with newer Android Gradle plugin version

I'm not sure if this issue should be put here or in https://github.com/bytedeco/sample-projects, sorry if I misplace it.

So, the current example for Android uses com.android.tools.build:gradle:4.1.1 and it builds fine, but when I update the Android plugin to 7.1.3, the project won't build complaining that jniNativeLibrary.cpp and jnijavacpp.cpp cannot be found:

Build command failed.
Error while executing process C:\Users\<my username>\AppData\Local\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C <my project path>\gradle-javacpp-android\app\.cxx\Debug\3n4fu1n1\arm64-v8a native-lib}
ninja: Entering directory `<my project path>\gradle-javacpp-android\app\.cxx\Debug\3n4fu1n1\arm64-v8a'
[1/3] Building CXX object CMakeFiles/native-lib.dir/jniNativeLibrary.cpp.o
FAILED: CMakeFiles/native-lib.dir/jniNativeLibrary.cpp.o 
C:\Users\<my username>\AppData\Local\Android\Sdk\ndk\21.4.7075529\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android21 --gcc-toolchain=C:/Users/<my username>/AppData/Local/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=C:/Users/<my username>/AppData/Local/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/windows-x86_64/sysroot  -Dnative_lib_EXPORTS  -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -fPIC -MD -MT CMakeFiles/native-lib.dir/jniNativeLibrary.cpp.o -MF CMakeFiles\native-lib.dir\jniNativeLibrary.cpp.o.d -o CMakeFiles/native-lib.dir/jniNativeLibrary.cpp.o -c <my project path>/gradle-javacpp-android/app/src/main/cpp/jniNativeLibrary.cpp
clang++: error: no such file or directory: '<my project path>/gradle-javacpp-android/app/src/main/cpp/jniNativeLibrary.cpp'
clang++: error: no input files
[2/3] Building CXX object CMakeFiles/native-lib.dir/jnijavacpp.cpp.o
FAILED: CMakeFiles/native-lib.dir/jnijavacpp.cpp.o 
C:\Users\<my username>\AppData\Local\Android\Sdk\ndk\21.4.7075529\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android21 --gcc-toolchain=C:/Users/<my username>/AppData/Local/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=C:/Users/<my username>/AppData/Local/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/windows-x86_64/sysroot  -Dnative_lib_EXPORTS  -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -fPIC -MD -MT CMakeFiles/native-lib.dir/jnijavacpp.cpp.o -MF CMakeFiles\native-lib.dir\jnijavacpp.cpp.o.d -o CMakeFiles/native-lib.dir/jnijavacpp.cpp.o -c <my project path>/gradle-javacpp-android/app/src/main/cpp/jnijavacpp.cpp
clang++: error: no such file or directory: '<my project path>/gradle-javacpp-android/app/src/main/cpp/jnijavacpp.cpp'
clang++: error: no input files
ninja: build stopped: subcommand failed.

And indeed jniNativeLibrary.cpp and jnijavacpp.cpp are not built. I figure that probably JavaCpp tasks dependencies need to be changed in app/build.gradle, but I'm struggling to do it on my own. Can you please update the example project?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.