Как создать правильный CMakeLists.txt для кода JNI и C ++? - PullRequest
1 голос
/ 28 мая 2020

Моя цель :

Я пытаюсь создать интерфейс java и C ++ для простого проекта, чтобы проверить, является ли число четным или нечетным. Код java должен генерировать файлы заголовков C ++, а затем я бы написал определения функций для функции java изнутри C ++ и создал файл библиотеки (.so). Позже я запущу код java для вывода на печать вывода, созданного C ++. Для этого я написал простой класс java, а затем функцию-член C ++, используя этот учебник .

Мой код очень тривиален. Я воспроизвел его ниже:

OddNumCheck. 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));
   }
}

OddNumCheck.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

OddNumCheck. 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

Мне удалось скомпилировать код и сгенерировать библиотеку (.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

UPDATE :

Я также пробовал этот файл CMakeLists.txt . Это тоже бесполезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...