CMake JNI error

北城余情 提交于 2020-08-04 09:33:08

问题


I've written a binding C++ class that calls java from C++. I am trying to compile the binding class using CMake (because the tool that will use the binding class uses CMake).

However I receive the following error:

CMakeFiles/JNIWrapper.dir/JNIWrapper.cpp.o: In function `createVM(JavaVM_**)':
JNIWrapper.cpp:(.text+0x52): undefined reference to `JNI_CreateJavaVM'
collect2: ld returned 1 exit status
make[2]: *** [JNIWrapper] Error 1
make[1]: *** [CMakeFiles/JNIWrapper.dir/all] Error 2
make: *** [all] Error 2

Here is my CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.6)

project(AProject)

FIND_PACKAGE(JNI REQUIRED)

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/lib/jvm/java-6-openjdk-amd64/include -I/usr/lib/jvm/java-6-openjdk-amd64/include/linux -L/usr/lib/jvm/java-6-openjdk-amd64/jre/lib/amd64/server")

SET(CMAKE_EXE_LINKER_FLAGS "-ljvm")

# add the binary tree directory to the search path for include files
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${JNI_INCLUDE_DIRS})

# add the executable
add_executable (JNIWrapper JNIWrapper.cpp)

Any suggestion is appreciated.

PS: I have tried to compile it using the traditional way and by writing a makefile. I followed that example and wrote the CMakeLists.txt script above.


回答1:


The following CMakeLists.txt sketches the steps required to build a sample JNI project with CMake:

cmake_minimum_required (VERSION 3.0)

find_package(Java REQUIRED)
find_package(JNI REQUIRED)
include(UseJava)

enable_testing()
project (JNIFoo)

# compile JNIFoo.java to class file
set(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.6" "-target" "1.6")
add_jar(JNIFoo JNIFoo.java)
get_target_property(_jarFile JNIFoo JAR_FILE)
get_target_property(_classDir JNIFoo CLASSDIR)

# generate JNIFoo.h stub
set (_stubDir "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_command(
    OUTPUT JNIFoo.h
    COMMAND ${Java_JAVAH_EXECUTABLE} -verbose
        -classpath ${_classDir}
        -d ${_stubDir}
        -jni JNIFoo
    DEPENDS JNIFoo
    )

# generate libfoo.jnilib
include_directories(${JNI_INCLUDE_DIRS} ${_classDir} ${_stubDir})
add_library(foo MODULE foo.c JNIFoo.h)
set_target_properties(foo PROPERTIES SUFFIX ".jnilib")
target_link_libraries(foo ${JNI_LIBRARIES})

# add test to run JNIFoo
add_test(NAME TestJNIFoo
    COMMAND ${Java_JAVA_EXECUTABLE}
    -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}
    -cp ${_jarFile} JNIFoo)

The file JNIFoo.java contains a Java class that declares a function in foo.c as a native method nativeFoo. foo.c contains the C implementation of the method nativeFoo.

The CMake function add_jar compiles the Java class to a jar file and, as a side effect, creates a class file which needs to be passed as an input to the javah C stub file generator executable. A custom command is used to invoke javah to generate the stub header JNIFoo.h as an output file.

Because Java uses System.loadLibrary to load JNI libraries at runtime, the JNI library must be generated as a MODULE library using the CMake command add_library. Adding JNIFoo.h as a source file ensures that JNIFoo.h will be created before the library is compiled. The compiled JNI library needs to be linked with the JDK JNI libraries contained in the variable JNI_LIBRARIES. JNI_INCLUDE_DIRS contains the the JNI include dirs to use.

Finally, a test is added to run the class JNIFoo with the JVM. The system property java.library.path must be set to the directory containing the generated JNI library libfoo.jnilib.



来源:https://stackoverflow.com/questions/18994344/cmake-jni-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!