1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-15 12:16:40 +08:00

UseJava: enable exportation of native headers target

This commit is contained in:
Marc Chevrier
2020-12-29 17:13:15 +01:00
parent c2a8d9b94e
commit 53235626a2
5 changed files with 87 additions and 5 deletions

View File

@@ -0,0 +1,6 @@
Java-export-native_headers-target
---------------------------------
* ``add_jar()`` command, from :module:`UseJava` module, gains new capabilities
for ``GENERATE_NATIVE_HEADERS`` option. These capabilities facilitate the
exportation of the generated target.

View File

@@ -23,7 +23,8 @@ Creating And Installing JARs
[VERSION <version>] [VERSION <version>]
[OUTPUT_NAME <name>] [OUTPUT_NAME <name>]
[OUTPUT_DIR <dir>] [OUTPUT_DIR <dir>]
[GENERATE_NATIVE_HEADERS <target> [DESTINATION <dir>]] [GENERATE_NATIVE_HEADERS <target>
[DESTINATION (<dir>|INSTALL <dir> [BUILD <dir>])]]
) )
This command creates a ``<target_name>.jar``. It compiles the given This command creates a ``<target_name>.jar``. It compiles the given
@@ -37,7 +38,7 @@ For backwards compatibility, jar files listed as sources are ignored (as
they have been since the first version of this module). they have been since the first version of this module).
.. versionadded:: 3.4 .. versionadded:: 3.4
Support fot response files (prefixed by ``@``) in the ``SOURCES`` list. Support for response files (prefixed by ``@``) in the ``SOURCES`` list.
The default ``OUTPUT_DIR`` can also be changed by setting the variable The default ``OUTPUT_DIR`` can also be changed by setting the variable
``CMAKE_JAVA_TARGET_OUTPUT_DIR``. ``CMAKE_JAVA_TARGET_OUTPUT_DIR``.
@@ -52,6 +53,12 @@ The default ``OUTPUT_DIR`` can also be changed by setting the variable
``GENERATE_NATIVE_HEADERS`` option requires, at least, version 1.8 of the JDK. ``GENERATE_NATIVE_HEADERS`` option requires, at least, version 1.8 of the JDK.
.. versionadded:: 3.20
``DESTINATION`` sub-option now supports the possibility to specify different
output directories for ``BUILD`` and ``INSTALL`` steps. This is required to
export the interface target generated by ``GENERATE_NATIVE_HEADERS`` option.
If ``BUILD`` directory is not specified, a default directory will be used.
The ``add_jar()`` function sets the following target properties on The ``add_jar()`` function sets the following target properties on
``<target_name>``: ``<target_name>``:
@@ -66,6 +73,11 @@ The ``add_jar()`` function sets the following target properties on
The directory where the class files can be found. For example to use them The directory where the class files can be found. For example to use them
with ``javah``. with ``javah``.
.. versionadded:: 3.20
The target generated by option ``GENERATE_NATIVE_HEADERS`` has the property
``NATIVE_HEADERS_DIRECTORY`` which specify the directory holding the native
headers.
.. code-block:: cmake .. code-block:: cmake
install_jar(<target_name> <destination>) install_jar(<target_name> <destination>)
@@ -217,6 +229,18 @@ native headers can then be used to compile C/C++ sources with the
add_library(bar bar.cpp) add_library(bar bar.cpp)
target_link_libraries(bar PRIVATE foo-native) target_link_libraries(bar PRIVATE foo-native)
.. versionadded:: 3.20
It is now possible to export the target generated by
``GENERATE_NATIVE_HEADERS`` option.
.. code-block:: cmake
add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native
DESTINATION INSTALL include)
install(TARGETS foo-native EXPORT native)
install(DIRECTORY "$<TARGET_PROPERTY:foo-native,NATIVE_HEADERS_DIRECTORY>/"
DESTINATION include)
install(EXPORT native DESTINATION /to/export NAMESPACE foo)
Finding JARs Finding JARs
^^^^^^^^^^^^ ^^^^^^^^^^^^
@@ -493,7 +517,10 @@ function(add_jar _TARGET_NAME)
if (Java_VERSION VERSION_LESS 1.8) if (Java_VERSION VERSION_LESS 1.8)
message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.") message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.")
endif() endif()
cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "DESTINATION" "" ${_add_jar_GENERATE_NATIVE_HEADERS})
unset (_GENERATE_NATIVE_HEADERS_OUTPUT_DESC)
cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "" "DESTINATION" ${_add_jar_GENERATE_NATIVE_HEADERS})
if (NOT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS) if (NOT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS)
message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: missing required argument.") message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: missing required argument.")
endif() endif()
@@ -504,11 +531,30 @@ function(add_jar _TARGET_NAME)
endif() endif()
if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION) 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") set (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers")
else()
list (LENGTH _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION length)
if (NOT length EQUAL 1)
cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "" "BUILD;INSTALL" "" "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}")
if (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS)
message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: ${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS}: unexpected argument(s).")
endif()
if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL)
message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: INSTALL sub-option is required.")
endif()
if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD)
set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers")
endif()
set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}")
set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "$<BUILD_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}>" "$<INSTALL_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL}>")
endif()
endif() endif()
set (_GENERATE_NATIVE_HEADERS_TARGET ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS}) 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_OUTPUT_DIR "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}")
set (_GENERATE_NATIVE_HEADERS -h "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") set (_GENERATE_NATIVE_HEADERS -h "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
if(NOT _GENERATE_NATIVE_HEADERS_OUTPUT_DESC)
set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
endif()
endif() endif()
if (LIBRARY_OUTPUT_PATH) if (LIBRARY_OUTPUT_PATH)
@@ -762,8 +808,9 @@ function(add_jar _TARGET_NAME)
# create an INTERFACE library encapsulating include directory for generated headers # create an INTERFACE library encapsulating include directory for generated headers
add_library (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE) add_library (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE)
target_include_directories (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE target_include_directories (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE
"${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}" "${_GENERATE_NATIVE_HEADERS_OUTPUT_DESC}"
${JNI_INCLUDE_DIRS}) ${JNI_INCLUDE_DIRS})
set_property(TARGET ${_GENERATE_NATIVE_HEADERS_TARGET} PROPERTY NATIVE_HEADERS_DIRECTORY "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
# this INTERFACE library depends on jar generation # this INTERFACE library depends on jar generation
add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME}) add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME})

View File

@@ -3394,6 +3394,9 @@ if(BUILD_TESTING)
${build_generator_args} ${build_generator_args}
--build-project helloJavaNativeHeaders --build-project helloJavaNativeHeaders
--build-run-dir "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/" --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/"
--build-target install
--build-options
"-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/Install"
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>) --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders") list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders")
endif() endif()

View File

@@ -11,7 +11,7 @@ include (UseJava)
# JNI support # JNI support
find_package(JNI) find_package(JNI)
add_jar(B1 D.java GENERATE_NATIVE_HEADERS D1-native) add_jar(B1 D.java GENERATE_NATIVE_HEADERS D1-native DESTINATION INSTALL include)
add_jar(E1 E.java GENERATE_NATIVE_HEADERS E1-native) add_jar(E1 E.java GENERATE_NATIVE_HEADERS E1-native)
add_jar(hello4 HelloWorld3.java) add_jar(hello4 HelloWorld3.java)
@@ -19,6 +19,13 @@ add_jar(hello4 HelloWorld3.java)
add_library(D SHARED D.cpp E.cpp) add_library(D SHARED D.cpp E.cpp)
target_link_libraries (D PRIVATE D1-native E1-native) target_link_libraries (D PRIVATE D1-native E1-native)
install(TARGETS D1-native EXPORT native)
install(DIRECTORY "$<TARGET_PROPERTY:D1-native,NATIVE_HEADERS_DIRECTORY>/" DESTINATION include)
install(EXPORT native DESTINATION "${CMAKE_INSTALL_PREFIX}" NAMESPACE D1::)
add_test (NAME Java.NativeHeaders add_test (NAME Java.NativeHeaders
COMMAND "${Java_JAVA_EXECUTABLE}" -Djava.library.path=$<TARGET_FILE_DIR:D> -classpath hello4.jar HelloWorld3) COMMAND "${Java_JAVA_EXECUTABLE}" -Djava.library.path=$<TARGET_FILE_DIR:D> -classpath hello4.jar HelloWorld3)
add_test (NAME Java.ImportNativeHeaders
COMMAND "${CMAKE_COMMAND}" "-DNATIVE_HEADERS_IMPORT_DIR=${CMAKE_INSTALL_PREFIX}" -S "${CMAKE_CURRENT_SOURCE_DIR}/Import" -B "${CMAKE_CURRENT_BINARY_DIR}/Import")

View File

@@ -0,0 +1,19 @@
project(ImportJavaNativeHeaders LANGUAGES NONE)
cmake_minimum_required (VERSION 3.19...3.20)
set(CMAKE_VERBOSE_MAKEFILE 1)
include(${NATIVE_HEADERS_IMPORT_DIR}/native.cmake)
if(NOT TARGET D1::D1-native)
message(FATAL_ERROR "Target 'D1::D1-native' not found.")
endif()
get_property(incs TARGET D1::D1-native PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
if (NOT incs MATCHES "${NATIVE_HEADERS_IMPORT_DIR}/include")
message(FATAL_ERROR "Target 'D1::D1-native', property 'INTERFACE_INCLUDE_DIRECTORIES' badly defined: ${incs}.")
endif()
if (NOT EXISTS "${NATIVE_HEADERS_IMPORT_DIR}/include/D.h")
message(FATAL_ERROR "file '${NATIVE_HEADERS_IMPORT_DIR}/include/D.h' not found.")
endif()