与Maven和JNI合作

时间:2018-02-28 11:26:42

标签: java maven cmake java-native-interface

我正在使用CMake调用Maven,它会生成一个JAR文件,我以后想要为其创建JNI标头。

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

set(PROJECT_TARGET_DIR "${CMAKE_CURRENT_SOURCE_DIR}/target")
set(PROJECT_JAR "core-${VERSION}.jar")

add_custom_command(
    OUTPUT "${PROJECT_TARGET_DIR}/${PROJECT_JAR}"
    COMMAND mvn clean install
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    VERBATIM
)
add_custom_target(
    JavaProject ALL
    DEPENDS "${PROJECT_TARGET_DIR}/${PROJECT_JAR}"
)
create_javah(
    TARGET JavaHeaders
    CLASSES com.some.class
    CLASSPATH "${PROJECT_TARGET_DIR}/${PROJECT_JAR}"
    DEPENDS JavaProject
    OUTPUT_NAME MyHeaders.h
)

此方法存在的问题是,JAR仅在构建时生成,但create_javah构建系统生成时检查CLASSPATH处的存在,即使我指定它取决于目标JavaProject

...
-- Found Java: /usr/lib/jvm/default-java/bin/java (found version "1.8.0.151") 
-- Found JNI: /usr/lib/jvm/default-java/jre/lib/amd64/libjawt.so  
CMake Error at /usr/share/cmake-3.9/Modules/UseJava.cmake:1293 (message):
  create_javah: CLASSPATH entry
  /path/to/target/core-5.12.0.3.jar does
  not exist.
Call Stack (most recent call first):
  jni/NsEttPos/CMakeLists.txt:17 (create_javah)

如何在生成时跳过此检查?

1 个答案:

答案 0 :(得分:1)

create_javah CLASSPATH选项可以指定目录,已存在的jar文件或使用add_jar命令创建的目标。仅当jar文件由CMake add_jar命令创建时,才允许它仅在构建时存在。

但是,由于create_javah仅检查是否存在JAR_FILE属性,因此您可以尝试应用以下hack:

add_custom_target(
    JavaProject ALL
    DEPENDS "${PROJECT_TARGET_DIR}/${PROJECT_JAR}"
)
# Add a JAR_FILE property to the JavaProject for create_javah
set_property(
    TARGET JavaProject 
    PROPERTY JAR_FILE "${PROJECT_TARGET_DIR}/${PROJECT_JAR}"
)

然后将JavaProject目标直接传递到create_javah CLASSPATH选项:

create_javah(
    TARGET JavaHeaders
    CLASSES com.some.class
    CLASSPATH JavaProject
    OUTPUT_NAME MyHeaders.h
)

另请注意,不再需要DEPENDS JavaProject,因为create_javah会自动为其添加依赖项。