java - 如何为 JNI 和 C++ 代码创建适当的 CMakeLists.txt?
问题描述
我的目标:
我正在尝试构建一个简单项目的 java 和 C++ 接口来检查数字是偶数还是奇数。java 代码应该生成 C++ 头文件,然后我将从 C++ 内部为 java 函数编写函数定义并构建一个库 (.so) 文件。稍后,我将运行 java 代码来打印 C++ 生成的输出。为此,我编写了一个简单的 java 类,然后使用本教程编写了 C++ 成员函数。
我的代码非常简单。我在下面复制了它:
奇数校验.java
public class OddNumCheck {
static {
System.loadLibrary("odd_num"); // libodd_num.so (MacOS/ Unix)
}
// Declare a native method odd_test() that receives an int and prints to the console whether it is odd or even
private native String odd_test(int num);
// Test Driver
public static void main(String args[]) {
System.out.println("In the Java program the given input number is " + new OddNumCheck().odd_test(3));
}
}
奇数校验.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class OddNumCheck */
#ifndef _Included_OddNumCheck
#define _Included_OddNumCheck
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: OddNumCheck
* Method: odd_test
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_OddNumCheck_odd_1test
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
奇数校验.cpp
#include <jni.h>
#include "OddNumCheck.h"
JNIEXPORT jstring
/*!
* @brief The odd_test function is a JNI function which takes an input integer from a java function odd_test() inside
* java a class OddNumCheck, and returns a string saying whether the passed integer is Odd or Even
* @param num a Java integer of type jint
* @return a java string with one of the two possibilities "Odd" or "Even"
* */
JNICALL Java_OddNumCheck_odd_1test(JNIEnv *env, jobject obj, jint num) {
jstring num_type;
if (num % 2 == 0) {
num_type = env->NewStringUTF("Even");
} else {
num_type = env->NewStringUTF("Odd");
}
return num_type;
}
这是我的项目结构:
OddNumCheck
|_ CMakeLists.txt
|_ OddNumCheck.cpp
|_ OddNumCheck.h
|_ OddNumCheck.java
我能够编译代码并生成一个 lib (.so) 文件,然后使用非 cmake 方法(在终端中键入手动编译指令)将输出打印到控制台。现在我正在尝试将东西打包成一个漂亮而干净的 CMakeLists.txt 文件,这将使我能够一次轻松地完成所有事情。
因此,我遵循了这个 CMakeLists.txt文件,该文件似乎与我正在寻找的内容非常相关,并按照其中的说明进行操作。
以下是我的CMakeLists.txt:
cmake_minimum_required (VERSION 3.0)
project (OddNumCheck)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
if (JNI_FOUND)
message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}")
message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}")
endif()
include(UseJava)
enable_testing()
# compile JNIFoo.java to class file
set(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.6" "-target" "1.6")
add_jar(OddNumCheck OddNumCheck.java)
get_target_property(_jarFile OddNumCheck JAR_FILE)
get_target_property(_classDir OddNumCheck CLASSDIR)
# generate JNIFoo.h stub
set (_stubDir "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_command(
OUTPUT OddNumCheck.h
COMMAND ${Java_JAVAH_EXECUTABLE} -verbose
-classpath ${_classDir}
-d ${_stubDir}
-jni OddNumCheck
DEPENDS OddNumCheck
)
# generate libfoo.jnilib
include_directories(${JNI_INCLUDE_DIRS} ${_classDir} ${_stubDir})
add_library(libodd_num MODULE OddNumCheck.cpp OddNumCheck.h)
set_target_properties(libodd_num PROPERTIES SUFFIX ".so")
target_link_libraries(libodd_num ${JNI_LIBRARIES})
# add test to run JNIFoo
add_test(NAME TestOddNumCheck
COMMAND ${Java_JAVA_EXECUTABLE}
-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}
-cp ${_jarFile} OddNumCheck)
不幸的是,我的 CMake 无法编译。我收到以下错误(来自 CLion IDE):
====================[ Build | all | Debug ]=====================================
/usr/local/bin/cmake --build /mnt/f/sandbox/OddNumCheck/cmake-build-debug --target all -- -j 6
[ 50%] Built target OddNumCheck
[ 66%] Generating OddNumCheck.h
make[2]: Java_JAVAH_EXECUTABLE-NOTFOUND: Command not found
CMakeFiles/libodd_num.dir/build.make:61: recipe for target 'OddNumCheck.h' failed
make[2]: *** [OddNumCheck.h] Error 127
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/libodd_num.dir/all' failed
make[1]: *** [CMakeFiles/libodd_num.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2
更新:
我也试过这个CMakeLists.txt文件。这也没有帮助。
解决方案
推荐阅读
- mysql - 使用springboot JPA使用Mysql上传图片
- angular - 如何对依赖服务的组件方法进行单元测试?
- html - 如何为 Instagram 创建链接
- docker - 带有子域的 docker-compose 中的 Traefik 配置
- javascript - 如何在鼠标悬停时显示 div 元素?
- python-3.x - tkinter python 3.7 如何使我的字符串变量可复制
- nginx - 如何在 NGINX 中使用子域?
- python - 如何在批量学习中为 tf-agents 定义正确的形状
- mongodb - 使用 logstash 将 mongo 数据同步到弹性
- android - 使用滚动工具栏隐藏状态栏