mirror of
https://github.com/Kitware/CMake.git
synced 2026-07-12 10:34:32 +00:00
add_jar: add option GENERATE_NATIVE_HEADERS
This commit is contained in:
9
Help/release/dev/UseJava-add_jar-native-headers.rst
Normal file
9
Help/release/dev/UseJava-add_jar-native-headers.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
UseJava-add_jar-native-headers
|
||||
------------------------------
|
||||
|
||||
* | The command add_jar from :module:`UseJava` module learns how to generate native
|
||||
headers files using option -h of javac tool.
|
||||
| This capability requires, at least, version 1.8 of Javac tool.
|
||||
| Command create_javah will no longer be supported due to the
|
||||
`suppression of javah tool <http://openjdk.java.net/jeps/313>`_ in the version 1.10
|
||||
of the JDK, so ``add_jar(GENERATE_NATIVE_HEADERS)`` must be used instead.
|
||||
@@ -20,6 +20,7 @@
|
||||
# [VERSION version]
|
||||
# [OUTPUT_NAME name]
|
||||
# [OUTPUT_DIR dir]
|
||||
# [GENERATE_NATIVE_HEADERS target [DESTINATION dir]]
|
||||
# )
|
||||
#
|
||||
# This command creates a <target_name>.jar. It compiles the given
|
||||
@@ -35,6 +36,14 @@
|
||||
# The default OUTPUT_DIR can also be changed by setting the variable
|
||||
# CMAKE_JAVA_TARGET_OUTPUT_DIR.
|
||||
#
|
||||
# Optionaly, using option GENERATE_NATIVE_HEADERS, native header files can be generated
|
||||
# for methods declared as native. These files provide the connective glue that allow your
|
||||
# Java and C code to interact. An INTERFACE target will be created for an easy usage
|
||||
# of generated files. Sub-option DESTINATION can be used to specify output directory for
|
||||
# generated header files.
|
||||
#
|
||||
# GENERATE_NATIVE_HEADERS option requires, at least, version 1.8 of the JDK.
|
||||
#
|
||||
# Additional instructions:
|
||||
#
|
||||
# ::
|
||||
@@ -168,6 +177,22 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# For an optimum usage of option GENERATE_NATIVE_HEADERS, it is recommended to
|
||||
# include module JNI before any call to add_jar. The produced target for native
|
||||
# headers can then be used to compile C/C++ sources with command
|
||||
# target_link_libraries.
|
||||
#
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# find_package(JNI)
|
||||
# add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native)
|
||||
# add_library(bar bar.cpp)
|
||||
# target_link_libraries(bar PRIVATE foo-native)
|
||||
#
|
||||
#
|
||||
# Target Properties:
|
||||
#
|
||||
# ::
|
||||
@@ -359,6 +384,10 @@
|
||||
# Create C header files from java classes. These files provide the connective glue
|
||||
# that allow your Java and C code to interact.
|
||||
#
|
||||
# This command will no longer be supported starting with version 1.10 of the JDK due
|
||||
# to the `suppression of javah tool <http://openjdk.java.net/jeps/313>`_.
|
||||
# Command ``add_jar(GENERATE_NATIVE_HEADERS)`` must be used instead.
|
||||
#
|
||||
# There are two main signatures for create_javah. The first signature
|
||||
# returns generated files through variable specified by GENERATED_FILES option:
|
||||
#
|
||||
@@ -448,7 +477,7 @@ function(add_jar _TARGET_NAME)
|
||||
cmake_parse_arguments(_add_jar
|
||||
""
|
||||
"VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT;MANIFEST"
|
||||
"SOURCES;INCLUDE_JARS"
|
||||
"SOURCES;INCLUDE_JARS;GENERATE_NATIVE_HEADERS"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
@@ -494,6 +523,31 @@ function(add_jar _TARGET_NAME)
|
||||
get_filename_component (_MANIFEST_VALUE "${_add_jar_MANIFEST}" ABSOLUTE)
|
||||
endif ()
|
||||
|
||||
unset (_GENERATE_NATIVE_HEADERS)
|
||||
if (_add_jar_GENERATE_NATIVE_HEADERS)
|
||||
# Raise an error if JDK version is less than 1.8 because javac -h is not supported
|
||||
# by earlier versions.
|
||||
if ("${Java_VERSION}" VERSION_LESS 1.8)
|
||||
message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.")
|
||||
endif()
|
||||
cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "DESTINATION" "" ${_add_jar_GENERATE_NATIVE_HEADERS})
|
||||
if (NOT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS)
|
||||
message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: missing required argument.")
|
||||
endif()
|
||||
list (LENGTH _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS length)
|
||||
if (length GREATER 1)
|
||||
list (REMOVE_AT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS 0)
|
||||
message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS}: unexpected argument(s).")
|
||||
endif()
|
||||
if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION)
|
||||
set (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers")
|
||||
endif()
|
||||
|
||||
set (_GENERATE_NATIVE_HEADERS_TARGET ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS})
|
||||
set (_GENERATE_NATIVE_HEADERS_OUTPUT_DIR "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}")
|
||||
set (_GENERATE_NATIVE_HEADERS -h "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
|
||||
endif()
|
||||
|
||||
if (LIBRARY_OUTPUT_PATH)
|
||||
set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH})
|
||||
else ()
|
||||
@@ -625,6 +679,7 @@ function(add_jar _TARGET_NAME)
|
||||
${CMAKE_JAVA_COMPILE_FLAGS}
|
||||
-classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
|
||||
-d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
|
||||
${_GENERATE_NATIVE_HEADERS}
|
||||
${_JAVA_SOURCES_FILELISTS}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
|
||||
DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS}
|
||||
@@ -735,6 +790,17 @@ function(add_jar _TARGET_NAME)
|
||||
${CMAKE_JAVA_CLASS_OUTPUT_PATH}
|
||||
)
|
||||
|
||||
if (_GENERATE_NATIVE_HEADERS)
|
||||
# create an INTERFACE library encapsulating include directory for generated headers
|
||||
add_library (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE)
|
||||
target_include_directories (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE
|
||||
"${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}"
|
||||
${JNI_INCLUDE_DIRS})
|
||||
# this INTERFACE library depends on jar generation
|
||||
add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME})
|
||||
|
||||
set_property (DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(INSTALL_JAR _TARGET_NAME)
|
||||
@@ -1246,6 +1312,12 @@ function(create_javadoc _target)
|
||||
endfunction()
|
||||
|
||||
function (create_javah)
|
||||
if ("${Java_VERSION}" VERSION_GREATER_EQUAL 1.10)
|
||||
message (FATAL_ERROR "create_javah: not supported with this Java version. Use add_jar(GENERATE_NATIVE_HEADERS) instead.")
|
||||
elseif ("${Java_VERSION}" VERSION_GREATER_EQUAL 1.8)
|
||||
message (DEPRECATION "create_javah: this command will no longer be supported starting with version 1.10 of JDK. Update your project by using command add_jar(GENERATE_NATIVE_HEADERS) instead.")
|
||||
endif()
|
||||
|
||||
cmake_parse_arguments(_create_javah
|
||||
""
|
||||
"TARGET;GENERATED_FILES;OUTPUT_NAME;OUTPUT_DIR"
|
||||
|
||||
@@ -3195,29 +3195,51 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
|
||||
--test-command ${JAVA_RUNTIME} -classpath hello3.jar HelloWorld)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJarSourceListAndOutput")
|
||||
|
||||
# For next test, java tool must have same architecture as toolchain
|
||||
# For next tests, java tool must have same architecture as toolchain
|
||||
math(EXPR _object_mode "${CMAKE_SIZEOF_VOID_P} * 8")
|
||||
execute_process(
|
||||
COMMAND "${Java_JAVA_EXECUTABLE}" -d${_object_mode} -version
|
||||
OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE _result
|
||||
)
|
||||
if(_result EQUAL 0)
|
||||
if(_isMultiConfig)
|
||||
set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah/$<CONFIGURATION>)
|
||||
else()
|
||||
set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah)
|
||||
## next test is valid only if Java version is less than 1.10
|
||||
if ("${Java_VERSION}" VERSION_LESS 1.10)
|
||||
if(_isMultiConfig)
|
||||
set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah/$<CONFIGURATION>)
|
||||
else()
|
||||
set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah)
|
||||
endif()
|
||||
add_test(NAME Java.Javah COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/JavaJavah"
|
||||
"${CMake_BINARY_DIR}/Tests/JavaJavah"
|
||||
${build_generator_args}
|
||||
--build-project helloJavah
|
||||
--build-two-config
|
||||
--build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJavah/"
|
||||
--build-options ${build_options}
|
||||
--test-command ${JAVA_RUNTIME} -Djava.library.path=${JAVAH_LIBRARY_PATH} -classpath hello3.jar HelloWorld2)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJavah")
|
||||
endif()
|
||||
## next test is valid only if Java is, at least, version 1.8
|
||||
if (NOT "${Java_VERSION}" VERSION_LESS 1.8)
|
||||
if(_isMultiConfig)
|
||||
set (JAVANATIVEHEADERS_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/$<CONFIGURATION>)
|
||||
else()
|
||||
set (JAVANATIVEHEADERS_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaNativeHeaders)
|
||||
endif()
|
||||
add_test(NAME Java.NativeHeaders COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/JavaNativeHeaders"
|
||||
"${CMake_BINARY_DIR}/Tests/JavaNativeHeaders"
|
||||
${build_generator_args}
|
||||
--build-project helloJavaNativeHeaders
|
||||
--build-two-config
|
||||
--build-run-dir "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/"
|
||||
--build-options ${build_options}
|
||||
--test-command ${JAVA_RUNTIME} -Djava.library.path=${JAVANATIVEHEADERS_LIBRARY_PATH} -classpath hello4.jar HelloWorld3)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders")
|
||||
endif()
|
||||
add_test(NAME Java.Javah COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/JavaJavah"
|
||||
"${CMake_BINARY_DIR}/Tests/JavaJavah"
|
||||
${build_generator_args}
|
||||
--build-project helloJavah
|
||||
--build-two-config
|
||||
--build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJavah/"
|
||||
--build-options ${build_options}
|
||||
--test-command ${JAVA_RUNTIME} -Djava.library.path=${JAVAH_LIBRARY_PATH} -classpath hello3.jar HelloWorld2)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJavah")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
18
Tests/JavaNativeHeaders/CMakeLists.txt
Normal file
18
Tests/JavaNativeHeaders/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
project(helloJavaNativeHeaders Java CXX)
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
set(CMAKE_VERBOSE_MAKEFILE 1)
|
||||
|
||||
find_package(Java COMPONENTS Development)
|
||||
include (UseJava)
|
||||
|
||||
# JNI support
|
||||
find_package(JNI)
|
||||
|
||||
add_jar(B1 D.java GENERATE_NATIVE_HEADERS D1-native)
|
||||
add_jar(E1 E.java GENERATE_NATIVE_HEADERS E1-native)
|
||||
|
||||
add_jar(hello4 HelloWorld3.java)
|
||||
|
||||
add_library(D SHARED D.cpp E.cpp)
|
||||
target_link_libraries (D PRIVATE D1-native E1-native)
|
||||
10
Tests/JavaNativeHeaders/D.cpp
Normal file
10
Tests/JavaNativeHeaders/D.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#include <jni.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "D.h"
|
||||
|
||||
JNIEXPORT void JNICALL Java_D_printName(JNIEnv*, jobject)
|
||||
{
|
||||
printf("D\n");
|
||||
}
|
||||
19
Tests/JavaNativeHeaders/D.java
Normal file
19
Tests/JavaNativeHeaders/D.java
Normal file
@@ -0,0 +1,19 @@
|
||||
class D
|
||||
{
|
||||
public D()
|
||||
{
|
||||
}
|
||||
|
||||
public native void printName();
|
||||
|
||||
static {
|
||||
try {
|
||||
|
||||
System.loadLibrary("D");
|
||||
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Tests/JavaNativeHeaders/E.cpp
Normal file
10
Tests/JavaNativeHeaders/E.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#include <jni.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "E.h"
|
||||
|
||||
JNIEXPORT void JNICALL Java_E_printName(JNIEnv*, jobject)
|
||||
{
|
||||
printf("E\n");
|
||||
}
|
||||
19
Tests/JavaNativeHeaders/E.java
Normal file
19
Tests/JavaNativeHeaders/E.java
Normal file
@@ -0,0 +1,19 @@
|
||||
class E
|
||||
{
|
||||
public E()
|
||||
{
|
||||
}
|
||||
|
||||
public native void printName();
|
||||
|
||||
static {
|
||||
try {
|
||||
|
||||
System.loadLibrary("D");
|
||||
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Tests/JavaNativeHeaders/HelloWorld3.java
Normal file
15
Tests/JavaNativeHeaders/HelloWorld3.java
Normal file
@@ -0,0 +1,15 @@
|
||||
class HelloWorld3
|
||||
{
|
||||
public static void main(String args[])
|
||||
{
|
||||
D d;
|
||||
d = new D();
|
||||
d.printName();
|
||||
|
||||
E e;
|
||||
e = new E();
|
||||
e.printName();
|
||||
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user