Native dependencies in gradle

I want to build a java project with several dependencies in gradle,
some are jar dependencies from the maven central repository, some are
other java project dependencies, but there is also a native JNI
dependency. I’ve managed to build the native dependency with gradle as a
seperate project.

Now I want to import the compiled .so library as a depedency in my java project. I thought it would work something like this:

dependencies {
    compile project(':nameofnativedependency')
}

The project is also listed in my settings.gradle file. However, when I compile the project, I can get an error:

Could not determine the dependencies of task ':test

Configuration with name ‘default’ not found.

So something must be misconfigured. What is the right way (I hope
there is one) to compile a native project and import the .so file in the
calling project?

2 Likes

If you use a dependency on a project Gradle will try to resolve the default configuration which doesn’t exist in your case. What you can do is to declare an explicit dependency on a file:

dependencies {
   compile files('path/to/lib.so')
}

Ideally you should have some task that produces the the native library, so you could write something like:

dependencies {
   compile files(project(':nameofnativedependency').createLibrary.outputFile)
}

thanks for the help.

when I insert the command

dependencies {
   compile files(project(':nameofnativedependency').createLibrary.outputFile)
}

in my build.gradle file and do a build of the project, I get the following error message:

What went wrong:
A problem occurred evaluating project ‘:common’.
Could not find property ‘createLibraries’ on project ‘:native’.

common is the java project i want to build with cpp depedencies. native is the cpp project.

Maybe my gradle.build file for the native project isn’t configured right?

Here is the code:

apply plugin: 'cpp'

model {
    buildTypes {
        release
    }

    platforms {
        x86 {
            architecture "x86"
        }
        x64 {
            architecture "x86_64"
        }
    }

    components {
        binaries.all {
            cppCompiler.args "-I$System.env.JAVA_HOME/include"
            cppCompiler.args "-I$System.env.JAVA_HOME/include/linux"
        }
        calibration(NativeLibrarySpec) {
            sources {
                cpp {
                    source {
                        srcDir "src/calibration/cpp"
                        include "*.cpp"
                    }
                }
            }
        }
        data(NativeLibrarySpec) {
            sources {
                cpp {
                    source {
                        srcDir "src/data/cpp"
                        include "*.cpp"
                    }
                }
            }
        }
        util(NativeLibrarySpec) {
            sources {
                cpp {
                    source {
                        srcDir "src/util/cpp"
                        include "*.cpp"
                    }
                }
            }
        }        
    }
}

Sorry I should have made it clear that createLibrary is the name of the task which generates the binary. Since you are using the native plugin, the code should probably be something like:

dependencies {
   compile files(project(':native').calibration.outputFile)
}

But I’m not familiar with the native plugin so I’m unsure about the outputFile property. It must be something a bit more complex. Maybe @daz knows?

Something along these lines might work:

dependencies {
   compile files(project(':nameofnativedependency').binaries['nameOfStaticLibraryBinary'].staticLibraryFile)
}

You could determine the actual ‘nativeOfStaticLibraryBinary’ by running gradle components in the native project.
You might need to add an explicit evaluationDependsOn to ensure that the native project is fully evaluated before the project that declares the dependency.

thanks for your help.

when I insert the line you suggested, I get following error:

BinarySpec with name ‘:calibration’ not found.

when I run the gradle components command, I get following output:

Native library ‘calibration’

Source sets
C++ source 'calibration:cpp’
srcDir: src/calibration/cpp
includes: *.cpp

Binaries
Shared library 'calibration:sharedLibrary’
build using task: :calibrationSharedLibrary
platform: linux_x86-64
build type: release
flavor: default
tool chain: Tool chain ‘gcc’ (GNU GCC)
shared library file: build/binaries/calibrationSharedLibrary/libcalibration.so
Static library 'calibration:staticLibrary’
build using task: :calibrationStaticLibrary
platform: linux_x86-64
build type: release
flavor: default
tool chain: Tool chain ‘gcc’ (GNU GCC)
static library file: build/binaries/calibrationStaticLibrary/libcalibration.a

can you help me out with this?

2 Likes