FindJNI: added components and imported targets

pipelines/275876^2
Sergiu Deitsch 2022-03-13 15:56:33 +01:00
parent 35e92ec619
commit 171d45c039
19 changed files with 407 additions and 25 deletions

View File

@ -27,6 +27,7 @@ set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
set(CMake_TEST_FindIconv "ON" CACHE BOOL "")
set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
set(CMake_TEST_FindJNI "ON" CACHE BOOL "")
set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
set(CMake_TEST_FindLAPACK "All;static=1;Generic" CACHE STRING "")

View File

@ -31,6 +31,7 @@ set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
set(CMake_TEST_FindIconv "ON" CACHE BOOL "")
set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
set(CMake_TEST_FindJNI "ON" CACHE BOOL "")
set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
set(CMake_TEST_FindLAPACK "All;static=1;Generic" CACHE STRING "")

View File

@ -30,6 +30,7 @@ set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
set(CMake_TEST_FindIconv "ON" CACHE BOOL "")
set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
set(CMake_TEST_FindJNI "ON" CACHE BOOL "")
set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
set(CMake_TEST_FindLAPACK "All;static=1;Generic" CACHE STRING "")

View File

@ -0,0 +1,4 @@
FindJNI-targets
---------------
* The :module:`FindJNI` module now provides imported targets.

View File

@ -16,6 +16,24 @@ include files and libraries are. It also determines what the name of
the library is. The caller may set variable ``JAVA_HOME`` to specify a
Java installation prefix explicitly.
.. versionadded:: 3.24
Added imported targets, components ``AWT`` and ``JVM``.
Imported Targets
^^^^^^^^^^^^^^^^
.. versionadded:: 3.24
``JNI::JNI``
Main JNI target, defined only if ``jni.h`` was found.
``JNI::AWT``
Java AWT Native Interface (JAWT) library, defined only if component ``AWT`` was
found.
``JNI::JVM``
Java Virtual Machine (JVM) library, defined only if component ``JVM`` was found.
Result Variables
^^^^^^^^^^^^^^^^
@ -27,6 +45,8 @@ This module sets the following result variables:
The libraries to use (JAWT and JVM).
``JNI_FOUND``
``TRUE`` if JNI headers and libraries were found.
``JNI_<component>_FOUND``
.. versionadded:: 3.24
Cache Variables
^^^^^^^^^^^^^^^
@ -40,11 +60,27 @@ The following cache variables are also available to set or use:
``JAVA_INCLUDE_PATH``
The include path to ``jni.h``.
``JAVA_INCLUDE_PATH2``
The include path to ``jni_md.h`` and ``jniport.h``.
The include path to machine-dependant headers ``jni_md.h`` and ``jniport.h``.
The variable is defined only if ``jni.h`` depends on one of these headers.
``JAVA_AWT_INCLUDE_PATH``
The include path to ``jawt.h``.
#]=======================================================================]
cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW)
include(CheckSourceCompiles)
include(CMakePushCheckState)
include(FindPackageHandleStandardArgs)
if(NOT JNI_FIND_COMPONENTS)
set(JNI_FIND_COMPONENTS AWT JVM)
# For compatibility purposes, if no components are specified both are
# considered required.
set(JNI_FIND_REQUIRED_AWT TRUE)
set(JNI_FIND_REQUIRED_JVM TRUE)
endif()
# Expand {libarch} occurrences to java_libarch subdirectory(-ies) and set ${_var}
macro(java_append_library_directories _var)
# Determine java arch-specific library subdir
@ -328,10 +364,19 @@ set(_JNI_NORMAL_JAWT
)
foreach(search ${_JNI_SEARCHES})
find_library(JAVA_JVM_LIBRARY ${_JNI_${search}_JVM})
find_library(JAVA_AWT_LIBRARY ${_JNI_${search}_JAWT})
if(JAVA_JVM_LIBRARY)
break()
if(JVM IN_LIST JNI_FIND_COMPONENTS)
find_library(JAVA_JVM_LIBRARY ${_JNI_${search}_JVM}
DOC "Java Virtual Machine library"
)
endif(JVM IN_LIST JNI_FIND_COMPONENTS)
if(AWT IN_LIST JNI_FIND_COMPONENTS)
find_library(JAVA_AWT_LIBRARY ${_JNI_${search}_JAWT}
DOC "Java AWT Native Interface library"
)
if(JAVA_JVM_LIBRARY)
break()
endif()
endif()
endforeach()
unset(_JNI_SEARCHES)
@ -350,11 +395,46 @@ endif()
# add in the include path
find_path(JAVA_INCLUDE_PATH jni.h
${JAVA_AWT_INCLUDE_DIRECTORIES}
DOC "JNI include directory"
)
if(JAVA_INCLUDE_PATH)
if(CMAKE_C_COMPILER_LOADED)
set(_JNI_CHECK_LANG C)
elseif(CMAKE_CXX_COMPILER_LOADED)
set(_JNI_CHECK_LANG CXX)
else()
set(_JNI_CHECK_LANG FALSE)
endif()
# Skip the check if neither C nor CXX is loaded.
if(_JNI_CHECK_LANG)
cmake_push_check_state(RESET)
# The result of the following check is not relevant for the user as
# JAVA_INCLUDE_PATH2 will be added to REQUIRED_VARS if necessary.
set(CMAKE_REQUIRED_QUIET ON)
set(CMAKE_REQUIRED_INCLUDES ${JAVA_INCLUDE_PATH})
# Determine whether jni.h requires jni_md.h and add JAVA_INCLUDE_PATH2
# correspondingly to REQUIRED_VARS
check_source_compiles(${_JNI_CHECK_LANG}
"
#include <jni.h>
int main(void) { return 0; }
"
JNI_INCLUDE_PATH2_OPTIONAL)
cmake_pop_check_state()
else()
# If the above check is skipped assume jni_md.h is not needed.
set(JNI_INCLUDE_PATH2_OPTIONAL TRUE)
endif()
unset(_JNI_CHECK_LANG)
endif()
find_path(JAVA_INCLUDE_PATH2 NAMES jni_md.h jniport.h
PATHS
${JAVA_INCLUDE_PATH}
PATHS ${JAVA_INCLUDE_PATH}
${JAVA_INCLUDE_PATH}/darwin
${JAVA_INCLUDE_PATH}/win32
${JAVA_INCLUDE_PATH}/linux
@ -364,11 +444,28 @@ find_path(JAVA_INCLUDE_PATH2 NAMES jni_md.h jniport.h
${JAVA_INCLUDE_PATH}/hp-ux
${JAVA_INCLUDE_PATH}/alpha
${JAVA_INCLUDE_PATH}/aix
DOC "jni_md.h jniport.h include directory"
)
find_path(JAVA_AWT_INCLUDE_PATH jawt.h
${JAVA_INCLUDE_PATH}
)
if(AWT IN_LIST JNI_FIND_COMPONENTS)
find_path(JAVA_AWT_INCLUDE_PATH jawt.h
${JAVA_INCLUDE_PATH}
DOC "Java AWT Native Interface include directory"
)
endif()
# Set found components
if(JAVA_AWT_INCLUDE_PATH AND JAVA_AWT_LIBRARY)
set(JNI_AWT_FOUND TRUE)
else()
set(JNI_AWT_FOUND FALSE)
endif()
if(JAVA_JVM_LIBRARY)
set(JNI_JVM_FOUND TRUE)
else(JAVA_JVM_LIBRARY)
set(JNI_JVM_FOUND FALSE)
endif()
# Restore CMAKE_FIND_FRAMEWORK
if(DEFINED _JNI_CMAKE_FIND_FRAMEWORK)
@ -378,12 +475,17 @@ else()
unset(CMAKE_FIND_FRAMEWORK)
endif()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JNI DEFAULT_MSG JAVA_AWT_LIBRARY
JAVA_JVM_LIBRARY
JAVA_INCLUDE_PATH
JAVA_INCLUDE_PATH2
JAVA_AWT_INCLUDE_PATH)
set(JNI_REQUIRED_VARS JAVA_INCLUDE_PATH)
if(NOT JNI_INCLUDE_PATH2_OPTIONAL)
list(APPEND JNI_REQUIRED_VARS JAVA_INCLUDE_PATH2)
endif()
find_package_handle_standard_args(JNI
REQUIRED_VARS ${JNI_REQUIRED_VARS}
${JNI_FPHSA_ARGS}
HANDLE_COMPONENTS
)
mark_as_advanced(
JAVA_AWT_LIBRARY
@ -393,13 +495,58 @@ mark_as_advanced(
JAVA_INCLUDE_PATH2
)
set(JNI_LIBRARIES
${JAVA_AWT_LIBRARY}
${JAVA_JVM_LIBRARY}
)
set(JNI_LIBRARIES)
set(JNI_INCLUDE_DIRS
${JAVA_INCLUDE_PATH}
${JAVA_INCLUDE_PATH2}
${JAVA_AWT_INCLUDE_PATH}
)
foreach(component IN LISTS JNI_FIND_COMPONENTS)
if(JNI_${component}_FOUND)
list(APPEND JNI_LIBRARIES ${JAVA_${component}_LIBRARY})
endif()
endforeach()
set(JNI_INCLUDE_DIRS ${JAVA_INCLUDE_PATH})
if(NOT JNI_INCLUDE_PATH2_OPTIONAL)
list(APPEND JNI_INCLUDE_DIRS ${JAVA_INCLUDE_PATH2})
endif()
if(JNI_FIND_REQUIRED_AWT)
list(APPEND JNI_INCLUDE_DIRS ${JAVA_AWT_INCLUDE_PATH})
endif()
if(JNI_FOUND)
if(NOT TARGET JNI::JNI)
add_library(JNI::JNI IMPORTED INTERFACE)
endif()
set_property(TARGET JNI::JNI PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${JAVA_INCLUDE_PATH})
if(NOT JNI_INCLUDE_PATH2_OPTIONAL AND JAVA_INCLUDE_PATH2)
set_property(TARGET JNI::JNI APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${JAVA_INCLUDE_PATH2})
endif()
if(JNI_AWT_FOUND)
if(NOT TARGET JNI::AWT)
add_library(JNI::AWT IMPORTED UNKNOWN)
endif(NOT TARGET JNI::AWT)
set_property(TARGET JNI::AWT PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${JAVA_AWT_INCLUDE_PATH})
set_property(TARGET JNI::AWT PROPERTY IMPORTED_LOCATION
${JAVA_AWT_LIBRARY})
set_property(TARGET JNI::AWT PROPERTY INTERFACE_LINK_LIBRARIES JNI::JNI)
endif()
if(JNI_JVM_FOUND)
if(NOT TARGET JNI::JVM)
add_library(JNI::JVM IMPORTED UNKNOWN)
endif(NOT TARGET JNI::JVM)
set_property(TARGET JNI::JVM PROPERTY IMPORTED_LOCATION
${JAVA_JVM_LIBRARY})
set_property(TARGET JNI::JVM PROPERTY INTERFACE_LINK_LIBRARIES JNI::JNI)
endif()
endif()
cmake_policy(POP)

View File

@ -1455,6 +1455,7 @@ if(BUILD_TESTING)
ICU
Intl
Jasper
JNI
JPEG
JsonCpp
LAPACK

View File

@ -0,0 +1,7 @@
class AWTTgt
{
public static void main(String[] args)
{
System.loadLibrary("AWTTgt");
}
}

View File

@ -0,0 +1,7 @@
class AWTVar
{
public static void main(String[] args)
{
System.loadLibrary("AWTVar");
}
}

View File

@ -0,0 +1,31 @@
cmake_minimum_required (VERSION 3.23)
project (TestAWT)
find_package (JNI REQUIRED COMPONENTS AWT)
find_package (Java REQUIRED COMPONENTS Runtime Development)
add_library (AWTTgt MODULE awt.cxx)
target_link_libraries (AWTTgt PRIVATE JNI::AWT)
add_library (AWTVar MODULE awt.cxx)
target_include_directories (AWTVar PRIVATE ${JNI_INCLUDE_DIRS})
target_link_libraries (AWTVar PRIVATE ${JNI_LIBRARIES})
enable_testing ()
foreach (test AWTTgt AWTVar)
add_test (NAME Compile${test} COMMAND ${Java_JAVAC_EXECUTABLE}
${TestAWT_SOURCE_DIR}/${test}.java)
add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E remove
${TestAWT_SOURCE_DIR}/${test}.class)
add_test (NAME ${test} COMMAND ${Java_JAVA_EXECUTABLE}
-cp ${TestAWT_SOURCE_DIR}
-Djava.library.path=$<TARGET_FILE_DIR:${test}>
${test}
)
set_tests_properties (Compile${test} PROPERTIES FIXTURES_SETUP Init${test})
set_tests_properties (Remove${test} PROPERTIES FIXTURES_CLEANUP Init${test})
set_tests_properties (${test} PROPERTIES FIXTURES_REQUIRED Init${test})
endforeach ()

23
Tests/FindJNI/AWT/awt.cxx Normal file
View File

@ -0,0 +1,23 @@
#include <jawt.h>
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
void* tmp;
if (vm->GetEnv(&tmp, JNI_VERSION_1_2) != JNI_OK) {
return -1;
}
JAWT awt;
awt.version = JAWT_VERSION_1_3;
if (JAWT_GetAWT(static_cast<JNIEnv*>(tmp), &awt) == JNI_FALSE) {
return -1;
}
return JNI_VERSION_1_2;
}
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved)
{
}

View File

@ -0,0 +1,12 @@
foreach(test IN ITEMS Minimal JVM AWT)
add_test(NAME FindJNI.${test} COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
"${CMake_SOURCE_DIR}/Tests/FindJNI/${test}"
"${CMake_BINARY_DIR}/Tests/FindJNI/${test}"
${build_generator_args}
--build-project Test${test}
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
endforeach()

View File

@ -0,0 +1,31 @@
cmake_minimum_required (VERSION 3.23)
project (TestJVM)
find_package (JNI REQUIRED COMPONENTS JVM)
find_package (Java REQUIRED COMPONENTS Runtime Development)
add_library (JVMTgt MODULE jvm.cxx)
target_link_libraries (JVMTgt PRIVATE JNI::JVM)
add_library (JVMVar MODULE jvm.cxx)
target_include_directories (JVMVar PRIVATE ${JNI_INCLUDE_DIRS})
target_link_libraries (JVMVar PRIVATE ${JNI_LIBRARIES})
enable_testing ()
foreach (test JVMTgt JVMVar)
add_test (NAME Compile${test} COMMAND ${Java_JAVAC_EXECUTABLE}
${TestJVM_SOURCE_DIR}/${test}.java)
add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E remove
${TestJVM_SOURCE_DIR}/${test}.class)
add_test (NAME ${test} COMMAND ${Java_JAVA_EXECUTABLE}
-cp ${TestJVM_SOURCE_DIR}
-Djava.library.path=$<TARGET_FILE_DIR:${test}>
${test}
)
set_tests_properties (Compile${test} PROPERTIES FIXTURES_SETUP Init${test})
set_tests_properties (Remove${test} PROPERTIES FIXTURES_CLEANUP Init${test})
set_tests_properties (${test} PROPERTIES FIXTURES_REQUIRED Init${test})
endforeach ()

View File

@ -0,0 +1,7 @@
class JVMTgt
{
public static void main(String[] args)
{
System.loadLibrary("JVMTgt");
}
}

View File

@ -0,0 +1,7 @@
class JVMVar
{
public static void main(String[] args)
{
System.loadLibrary("JVMVar");
}
}

15
Tests/FindJNI/JVM/jvm.cxx Normal file
View File

@ -0,0 +1,15 @@
#include <jni.h>
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
jsize n = 0;
if (JNI_GetCreatedJavaVMs(nullptr, 0, &n) != JNI_OK || n <= 0) {
return -1;
}
return JNI_VERSION_1_2;
}
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved)
{
}

View File

@ -0,0 +1,35 @@
cmake_minimum_required (VERSION 3.23)
project (TestMinimal)
set (CMAKE_CXX_VISIBILITY_PRESET hidden)
find_package (JNI REQUIRED)
find_package (Java REQUIRED COMPONENTS Runtime Development)
add_library (MinimalTgt MODULE minimal.cxx)
target_link_libraries (MinimalTgt PRIVATE JNI::JNI)
add_library (MinimalVar MODULE minimal.cxx)
target_include_directories (MinimalVar PRIVATE ${JNI_INCLUDE_DIRS})
target_link_libraries (MinimalVar PRIVATE ${JNI_LIBRARIES})
enable_testing ()
foreach (test MinimalTgt MinimalVar)
add_test (NAME Compile${test} COMMAND ${Java_JAVAC_EXECUTABLE}
${TestMinimal_SOURCE_DIR}/${test}.java)
add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E remove
${TestMinimal_SOURCE_DIR}/${test}.class)
add_test (NAME ${test} COMMAND ${Java_JAVA_EXECUTABLE}
-cp ${TestMinimal_SOURCE_DIR}
-Djava.library.path=$<TARGET_FILE_DIR:${test}>
${test}
)
set_tests_properties (Compile${test} PROPERTIES FIXTURES_SETUP Init${test})
set_tests_properties (Remove${test} PROPERTIES FIXTURES_CLEANUP Init${test})
set_tests_properties (${test} PROPERTIES FIXTURES_REQUIRED Init${test})
set_tests_properties (${test} PROPERTIES PASS_REGULAR_EXPRESSION "^FindJNI\n$")
endforeach ()

View File

@ -0,0 +1,7 @@
class MinimalTgt
{
public static void main(String[] args)
{
System.loadLibrary("MinimalTgt");
}
}

View File

@ -0,0 +1,7 @@
class MinimalVar
{
public static void main(String[] args)
{
System.loadLibrary("MinimalVar");
}
}

View File

@ -0,0 +1,38 @@
#include <cassert>
#include <jni.h>
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
void* tmp;
if (vm->GetEnv(&tmp, JNI_VERSION_1_2) != JNI_OK) {
return -1;
}
// The following lines do:
//
// System.out.println("FindJNI");
//
JNIEnv* env = static_cast<JNIEnv*>(tmp);
jclass clzS = env->FindClass("java/lang/System");
jclass clzP = env->FindClass("java/io/PrintStream");
jfieldID outF = env->GetStaticFieldID(clzS, "out", "Ljava/io/PrintStream;");
jobject out = env->GetStaticObjectField(clzS, outF);
jmethodID println =
env->GetMethodID(clzP, "println", "(Ljava/lang/String;)V");
env->CallVoidMethod(out, println, env->NewStringUTF("FindJNI"));
return JNI_VERSION_1_2;
}
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved)
{
void* env;
jint result = vm->GetEnv(&env, JNI_VERSION_1_2);
assert(result == JNI_OK);
assert(static_cast<JNIEnv*>(env)->GetVersion() == JNI_VERSION_1_2);
}