Я пытаюсь написать Java привязок для библиотеки C ++ и пытаюсь использовать для нее gradle.
Если у меня есть заголовок try.h
и общая библиотека libtry.so
, я хочу использовать его в моем проекте gradle. Я пытаюсь сделать это следующим образом:
Вот файл build.gradle
:
import org.gradle.internal.jvm.Jvm
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.2.2/userguide/java_library_plugin.html
*/
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'cpp'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.1-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
test {
systemProperty "java.library.path", file("${buildDir}/libs/hello/shared").absolutePath
}
model {
platforms {
x64 {
architecture "x64"
}
}
components {
hello(NativeLibrarySpec) {
binaries.all {
if (targetPlatform.operatingSystem.macOsX) {
cppCompiler.args '-I', "${Jvm.current().javaHome}/include"
cppCompiler.args '-I', "${Jvm.current().javaHome}/include/darwin"
cppCompiler.args '-I', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-L', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-l', "try"
cppCompiler.args '-mmacosx-version-min=10.4'
linker.args '-mmacosx-version-min=10.4'
} else if (targetPlatform.operatingSystem.linux) {
cppCompiler.args '-I', "${Jvm.current().javaHome}/include"
cppCompiler.args '-I', "${Jvm.current().javaHome}/include/linux"
cppCompiler.args '-I', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-L', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-l', "try"
cppCompiler.args '-D_FILE_OFFSET_BITS=64'
} else if (targetPlatform.operatingSystem.windows) {
cppCompiler.args "-I${Jvm.current().javaHome}/include"
cppCompiler.args "-I${Jvm.current().javaHome}/include/win32"
cppCompiler.args '-I', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-L', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-l', "try"
linker.args "Shlwapi.lib", "Advapi32.lib"
} else if (targetPlatform.operatingSystem.freeBSD) {
cppCompiler.args '-I', "${Jvm.current().javaHome}/include"
cppCompiler.args '-I', "${Jvm.current().javaHome}/include/freebsd"
cppCompiler.args '-I', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-L', "/home/karthik/gradle_try/HelloWorld/libs"
cppCompiler.args '-l', "try"
}
}
}
}
}
test.dependsOn 'helloSharedLibrary'
Другие соответствующие файлы находятся ниже:
hello.h
#include <jni.h>
/* Header for class HelloWorld_Library */
#ifndef _Included_HelloWorld_Library
#define _Included_HelloWorld_Library
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld_Library
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_Library_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
hello.cpp
#include "hello.h"
#include <try.h>
#include<iostream>
void Java_HelloWorld_Library_print(JNIEnv *env, jobject object)
{
ABC abc;
abc.sayFive();
std::cout<<"Hello World!";
}
Library.java
package HelloWorld;
public class Library {
public boolean someLibraryMethod() {
return true;
}
public native void print();
static {
System.loadLibrary("hello");
}
}
LibraryTest.java
package HelloWorld;
import org.junit.Test;
import static org.junit.Assert.*;
public class LibraryTest {
@Test public void testSomeLibraryMethod() {
Library classUnderTest = new Library();
classUnderTest.print();
assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
}
}
При строительстве я получаю эту ошибку:
> Task :test FAILED
/home/karthik/JDK/jdk-13.0.2/bin/java: symbol lookup error: /home/karthik/gradle_try/HelloWorld/build/libs/hello/shared/libhello.so: undefined symbol: _ZN3ABC7sayFiveEv
FAILURE: Build failed with an exception.
Что я делаю не так? Я указал каталог include и каталог ссылок и библиотеку, которые будут связаны в аргументах компилятора. Есть ли другой способ сделать это?
Кроме того, как я могу получить текущий каталог проекта или файл build.gradle? Указывать каталог включения для внешней библиотеки как абсолютный путь совсем не удобно.