VTK  9.1.0
vtkModuleWrapJava.cmake
Go to the documentation of this file.
1#[==[
2@defgroup module-wrapping-java Module Java CMake APIs
3#]==]
4
5#[==[
6@file vtkModuleWrapJava.cmake
7@brief APIs for wrapping modules for Java
8#]==]
9
10#[==[
11@ingroup module-impl
12@brief Generate sources for using a module's classes from Java
13
14This function generates the wrapped sources for a module. It places the list of
15generated source files and Java source files in variables named in the second
16and third arguments, respectively.
17
18~~~
19_vtk_module_wrap_java_sources(<module> <sources> <classes>)
20~~~
21#]==]
22
23cmake_policy(PUSH)
24cmake_policy(SET CMP0053 NEW)
25
26function (_vtk_module_wrap_java_sources module sources java_sources)
27 _vtk_module_get_module_property("${module}"
28 PROPERTY "exclude_wrap"
29 VARIABLE _vtk_java_exclude_wrap)
30 if (_vtk_java_exclude_wrap)
31 return ()
32 endif ()
33
34 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_java_library_name}Java")
35
36 set(_vtk_java_args_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_java_library_name}Java/${_vtk_java_library_name}-java.$<CONFIGURATION>.args")
37 set(_vtk_java_init_data_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_java_library_name}Java/${_vtk_java_library_name}-java-init.data")
38
39 set(_vtk_java_hierarchy_depends "${module}")
40 _vtk_module_get_module_property("${module}"
41 PROPERTY "private_depends"
42 VARIABLE _vtk_java_private_depends)
43 list(APPEND _vtk_java_hierarchy_depends
44 ${_vtk_java_private_depends})
45 _vtk_module_get_module_property("${module}"
46 PROPERTY "optional_depends"
47 VARIABLE _vtk_java_optional_depends)
48 foreach (_vtk_java_optional_depend IN LISTS _vtk_java_optional_depends)
49 if (TARGET "${_vtk_java_optional_depend}")
50 list(APPEND _vtk_java_hierarchy_depends
51 "${_vtk_java_optional_depend}")
52 endif ()
53 endforeach ()
54
55 set(_vtk_java_command_depends)
56 foreach (_vtk_java_hierarchy_depend IN LISTS _vtk_java_hierarchy_depends)
57 _vtk_module_get_module_property("${_vtk_java_hierarchy_depend}"
58 PROPERTY "hierarchy"
59 VARIABLE _vtk_java_hierarchy_file)
60 if (_vtk_java_hierarchy_file)
61 list(APPEND _vtk_java_hierarchy_files "${_vtk_java_hierarchy_file}")
62 get_property(_vtk_java_is_imported
63 TARGET "${_vtk_java_hierarchy_depend}"
64 PROPERTY "IMPORTED")
65 if (_vtk_java_is_imported OR CMAKE_GENERATOR MATCHES "Ninja")
66 list(APPEND _vtk_java_command_depends "${_vtk_java_hierarchy_file}")
67 else ()
68 _vtk_module_get_module_property("${_vtk_java_hierarchy_depend}"
69 PROPERTY "library_name"
70 VARIABLE _vtk_java_hierarchy_library_name)
71 if (TARGET "${_vtk_java_hierarchy_library_name}-hierarchy")
72 list(APPEND _vtk_java_command_depends "${_vtk_java_hierarchy_library_name}-hierarchy")
73 else ()
74 message(FATAL_ERROR
75 "The ${_vtk_java_hierarchy_depend} hierarchy file is attached to a non-imported target "
76 "and a hierarchy target (${_vtk_java_hierarchy_library_name}-hierarchy) is "
77 "missing.")
78 endif ()
79 endif ()
80 endif ()
81 endforeach ()
82
83 set(_vtk_java_genex_compile_definitions
84 "$<TARGET_PROPERTY:${_vtk_java_target_name},COMPILE_DEFINITIONS>")
85 set(_vtk_java_genex_include_directories
86 "$<TARGET_PROPERTY:${_vtk_java_target_name},INCLUDE_DIRECTORIES>")
87 file(GENERATE
88 OUTPUT "${_vtk_java_args_file}"
89 CONTENT "$<$<BOOL:${_vtk_java_genex_compile_definitions}>:\n-D\'$<JOIN:${_vtk_java_genex_compile_definitions},\'\n-D\'>\'>\n
90$<$<BOOL:${_vtk_java_genex_include_directories}>:\n-I\'$<JOIN:${_vtk_java_genex_include_directories},\'\n-I\'>\'>\n
91$<$<BOOL:${_vtk_java_hierarchy_files}>:\n--types \'$<JOIN:${_vtk_java_hierarchy_files},\'\n--types \'>\'>\n")
92
93 set(_vtk_java_sources)
94 set(_vtk_java_java_sources)
95
96 _vtk_module_get_module_property("${module}"
97 PROPERTY "headers"
98 VARIABLE _vtk_java_headers)
99 set(_vtk_java_classes)
100 foreach (_vtk_java_header IN LISTS _vtk_java_headers)
101 get_filename_component(_vtk_java_basename "${_vtk_java_header}" NAME_WE)
102 list(APPEND _vtk_java_classes
103 "${_vtk_java_basename}")
104
105 # The vtkWrapJava tool has special logic for the `vtkRenderWindow` class.
106 # This extra logic requires its wrappers to be compiled as ObjC++ code
107 # instead.
108 set(_vtk_java_ext "cxx")
109 if (APPLE AND _vtk_java_basename STREQUAL "vtkRenderWindow")
110 set(_vtk_java_ext "mm")
111 endif ()
112
113 set(_vtk_java_source_output
114 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_java_library_name}Java/${_vtk_java_basename}Java.${_vtk_java_ext}")
115 list(APPEND _vtk_java_sources
116 "${_vtk_java_source_output}")
117
118 set(_vtk_java_wrap_target "VTK::WrapJava")
119 set(_vtk_java_macros_args)
120 if (TARGET VTKCompileTools::WrapJava)
121 set(_vtk_java_wrap_target "VTKCompileTools::WrapJava")
122 if (TARGET VTKCompileTools_macros)
123 list(APPEND _vtk_java_command_depends
124 "VTKCompileTools_macros")
125 list(APPEND _vtk_java_macros_args
126 -undef
127 -imacros "${_VTKCompileTools_macros_file}")
128 endif ()
129 endif ()
130
131 set(_vtk_java_parse_target "VTK::ParseJava")
132 if (TARGET VTKCompileTools::ParseJava)
133 set(_vtk_java_parse_target "VTKCompileTools::ParseJava")
134 endif ()
135
136 add_custom_command(
137 OUTPUT "${_vtk_java_source_output}"
138 COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR}
139 "$<TARGET_FILE:${_vtk_java_wrap_target}>"
140 "@${_vtk_java_args_file}"
141 -o "${_vtk_java_source_output}"
142 "${_vtk_java_header}"
143 ${_vtk_java_macros_args}
144 IMPLICIT_DEPENDS
145 CXX "${_vtk_java_header}"
146 COMMENT "Generating Java wrapper sources for ${_vtk_java_basename}"
147 DEPENDS
148 "${_vtk_java_header}"
149 "${_vtk_java_args_file}"
150 "$<TARGET_FILE:${_vtk_java_wrap_target}>"
151 ${_vtk_java_command_depends})
152
153 set(_vtk_java_java_source_output
154 "${_vtk_java_JAVA_OUTPUT}/${_vtk_java_basename}.java")
155 list(APPEND _vtk_java_java_sources
156 "${_vtk_java_java_source_output}")
157
158 add_custom_command(
159 OUTPUT "${_vtk_java_java_source_output}"
160 COMMAND "${_vtk_java_parse_target}"
161 "@${_vtk_java_args_file}"
162 -o "${_vtk_java_java_source_output}"
163 "${_vtk_java_header}"
164 ${_vtk_java_macros_args}
165 IMPLICIT_DEPENDS
166 CXX "${_vtk_java_header}"
167 COMMENT "Generating Java sources for ${_vtk_java_basename}"
168 DEPENDS
169 "${_vtk_java_header}"
170 "${_vtk_java_args_file}"
171 "$<TARGET_FILE:${_vtk_java_parse_target}>"
172 ${_vtk_java_command_depends})
173 endforeach ()
174
175 set("${sources}"
176 "${_vtk_java_sources}"
177 PARENT_SCOPE)
178
179 set("${java_sources}"
180 "${_vtk_java_java_sources}"
181 PARENT_SCOPE)
182endfunction ()
183
184#[==[
185@ingroup module-impl
186@brief Generate a JNI library for a set of modules
187
188A single JNI library may consist of the Java wrappings of multiple modules.
189This is useful for kit-based builds where the modules part of the same kit
190belong to the same JNI library as well.
191
192~~~
193_vtk_module_wrap_java_library(<name> <module>...)
194~~~
195
196The first argument is the name of the JNI library. The remaining arguments are
197modules to include in the JNI library.
198
199The remaining information it uses is assumed to be provided by the
200@ref vtk_module_wrap_java function.
201#]==]
202function (_vtk_module_wrap_java_library name)
203 set(_vtk_java_library_sources)
204 set(_vtk_java_library_java_sources)
205 set(_vtk_java_library_link_depends)
206 foreach (_vtk_java_module IN LISTS ARGN)
207 _vtk_module_get_module_property("${_vtk_java_module}"
208 PROPERTY "exclude_wrap"
209 VARIABLE _vtk_java_exclude_wrap)
210 if (_vtk_java_exclude_wrap)
211 continue ()
212 endif ()
213 _vtk_module_real_target(_vtk_java_target_name "${_vtk_java_module}")
214 _vtk_module_get_module_property("${_vtk_java_module}"
215 PROPERTY "library_name"
216 VARIABLE _vtk_java_library_name)
217 _vtk_module_wrap_java_sources("${_vtk_java_module}" _vtk_java_sources _vtk_java_java_sources)
218 list(APPEND _vtk_java_library_sources
219 ${_vtk_java_sources})
220 list(APPEND _vtk_java_library_java_sources
221 ${_vtk_java_java_sources})
222
223 _vtk_module_get_module_property("${_vtk_java_module}"
224 PROPERTY "depends"
225 VARIABLE _vtk_java_module_depends)
226 foreach (_vtk_java_module_depend IN LISTS _vtk_java_module_depends)
227 _vtk_module_get_module_property("${_vtk_java_module_depend}"
228 PROPERTY "exclude_wrap"
229 VARIABLE _vtk_java_module_depend_exclude_wrap)
230 if (_vtk_java_module_depend_exclude_wrap)
231 continue ()
232 endif ()
233
234 _vtk_module_get_module_property("${_vtk_java_module_depend}"
235 PROPERTY "library_name"
236 VARIABLE _vtk_java_depend_library_name)
237
238 # XXX(kits): This doesn't work for kits.
239 list(APPEND _vtk_java_library_link_depends
240 "${_vtk_java_depend_library_name}Java")
241 endforeach ()
242 endforeach ()
243
244 if (NOT _vtk_java_library_sources)
245 return ()
246 endif ()
247
248 if (_vtk_java_library_link_depends)
249 list(REMOVE_DUPLICATES _vtk_java_library_link_depends)
250 endif ()
251
252 set(_vtk_java_target "${name}Java")
253
254 # XXX(java): Should this be a `MODULE`? If not, we should probably export
255 # these targets, but then we'll need logic akin to the `vtkModuleWrapPython`
256 # logic for loading wrapped modules from other packages.
257 add_library("${_vtk_java_target}" SHARED
258 ${_vtk_java_library_sources})
259
260 if (_vtk_java_UTILITY_TARGET)
261 target_link_libraries("${_vtk_java_target}"
262 PRIVATE
263 "${_vtk_java_UTILITY_TARGET}")
264 endif ()
265
266 add_custom_target("${_vtk_java_target}-java-sources"
267 DEPENDS
268 ${_vtk_java_library_java_sources})
269 add_dependencies("${_vtk_java_target}"
270 "${_vtk_java_target}-java-sources")
271 if (MINGW)
272 set_property(TARGET "${_vtk_java_target}"
273 PROPERTY
274 PREFIX "")
275 endif ()
276 if (APPLE)
277 set_property(TARGET "${_vtk_java_target}"
278 PROPERTY
279 SUFFIX ".jnilib")
280 endif ()
281 set_property(TARGET "${_vtk_java_target}"
282 PROPERTY
283 "_vtk_module_java_files" "${_vtk_java_library_java_sources}")
284
285 if (_vtk_java_JNILIB_DESTINATION)
286 install(
287 TARGETS "${_vtk_java_target}"
288 # Windows
289 RUNTIME
290 DESTINATION "${_vtk_java_JNILIB_DESTINATION}"
291 COMPONENT "${_vtk_java_JNILIB_COMPONENT}"
292 # Other platforms
293 LIBRARY
294 DESTINATION "${_vtk_java_JNILIB_DESTINATION}"
295 COMPONENT "${_vtk_java_JNILIB_COMPONENT}")
296 endif ()
297
298 vtk_module_autoinit(
299 MODULES ${ARGN}
300 TARGETS "${_vtk_java_target}")
301
302 target_link_libraries("${_vtk_java_target}"
303 PRIVATE
304 ${ARGN}
305 # XXX(java): If we use modules, remove this.
306 ${_vtk_java_library_link_depends}
307 VTK::Java)
308endfunction ()
309
310#[==[
311@ingroup module-wrapping-java
312@brief Wrap a set of modules for use in Java
313
314~~~
315vtk_module_wrap_java(
316 MODULES <module>...
317 [WRAPPED_MODULES <varname>]
318
319 [UTILITY_TARGET <target>]
320
321 [JAVA_OUTPUT <destination>]
322
323 [LIBRARY_DESTINATION <destination>]
324 [JNILIB_DESTINATION <destination>]
325 [JNILIB_COMPONENT <component>])
326~~~
327
328 * `MODULES`: (Required) The list of modules to wrap.
329 * `WRAPPED_MODULES`: (Recommended) Not all modules are wrappable. This
330 variable will be set to contain the list of modules which were wrapped.
331 * `UTILITY_TARGET`: If specified, all libraries made by the Java wrapping
332 will link privately to this target. This may be used to add compile flags
333 to the Java libraries.
334 * `JAVA_OUTPUT`: Defaults to
335 `${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/vtkJava`. Java source files are
336 written to this directory. After generation, the files may be compiled as
337 needed.
338 * `LIBRARY_DESTINATION` (Recommended): If provided, dynamic loader
339 information will be added to modules for loading dependent libraries.
340 * `JNILIB_DESTINATION`: Where to install JNI libraries.
341 * `JNILIB_COMPONENT`: Defaults to `jni`. The install component to use for JNI
342 libraries.
343
344For each wrapped module, a `<module>Java` target will be created. These targets
345will have a `_vtk_module_java_files` property which is the list of generated
346Java source files for that target.
347
348For dependency purposes, the `<module>Java-java-sources` target may also be
349used.
350#]==]
351function (vtk_module_wrap_java)
352 cmake_parse_arguments(PARSE_ARGV 0 _vtk_java
353 ""
354 "JAVA_OUTPUT;WRAPPED_MODULES;LIBRARY_DESTINATION;JNILIB_DESTINATION;JNILIB_COMPONENT;UTILITY_TARGET"
355 "MODULES")
356
357 if (_vtk_java_UNPARSED_ARGUMENTS)
358 message(FATAL_ERROR
359 "Unparsed arguments for vtk_module_wrap_java: "
360 "${_vtk_java_UNPARSED_ARGUMENTS}")
361 endif ()
362
363 if (NOT _vtk_java_JAVA_OUTPUT)
364 set(_vtk_java_JAVA_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/vtkJava")
365 endif ()
366
367 if (NOT _vtk_java_JNILIB_COMPONENT)
368 set(_vtk_java_JNILIB_COMPONENT "jni")
369 endif ()
370
371 # Set up rpaths
372 set(CMAKE_BUILD_RPATH_USE_ORIGIN 1)
373 if (UNIX)
374 if (APPLE)
375 set(_vtk_java_origin_rpath_prefix
376 "@loader_path")
377 else ()
378 set(_vtk_java_origin_rpath_prefix
379 "$ORIGIN")
380 endif ()
381
382 list(APPEND CMAKE_INSTALL_RPATH
383 # For sibling wrapped modules.
384 "${_vtk_java_origin_rpath_prefix}")
385
386 if (DEFINED _vtk_java_LIBRARY_DESTINATION AND DEFINED _vtk_java_JNILIB_DESTINATION)
387 file(RELATIVE_PATH _vtk_java_relpath
388 "/prefix/${_vtk_java_JNILIB_DESTINATION}"
389 "/prefix/${_vtk_java_LIBRARY_DESTINATION}")
390
391 list(APPEND CMAKE_INSTALL_RPATH
392 # For libraries.
393 "${_vtk_java_origin_rpath_prefix}/${_vtk_java_relpath}")
394 endif ()
395 endif ()
396
397 if (DEFINED _vtk_java_JNILIB_DESTINATION)
398 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_java_JNILIB_DESTINATION}")
399 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_java_JNILIB_DESTINATION}")
400 endif ()
401
402 if (NOT _vtk_java_MODULES)
403 message(WARNING
404 "No modules were requested for java wrapping.")
405 return ()
406 endif ()
407
408 # Disable CMake's automoc support for these targets.
409 set(CMAKE_AUTOMOC 0)
410 set(CMAKE_AUTORCC 0)
411 set(CMAKE_AUTOUIC 0)
412
413 set(_vtk_java_all_wrapped_modules)
414 foreach (_vtk_java_module IN LISTS _vtk_java_MODULES)
415 _vtk_module_get_module_property("${_vtk_java_module}"
416 PROPERTY "library_name"
417 VARIABLE _vtk_java_exclude_wrap)
418 _vtk_module_get_module_property("${_vtk_java_module}"
419 PROPERTY "library_name"
420 VARIABLE _vtk_java_library_name)
421 _vtk_module_wrap_java_library("${_vtk_java_library_name}" "${_vtk_java_module}")
422
423 if (TARGET "${_vtk_java_library_name}Java")
424 list(APPEND _vtk_java_all_wrapped_modules
425 "${_vtk_java_module}")
426 endif ()
427 endforeach ()
428
429 if (NOT _vtk_java_all_wrapped_modules)
430 message(FATAL_ERROR
431 "No modules given could be wrapped.")
432 endif ()
433
434 if (DEFINED _vtk_java_WRAPPED_MODULES)
435 set("${_vtk_java_WRAPPED_MODULES}"
436 "${_vtk_java_all_wrapped_modules}"
437 PARENT_SCOPE)
438 endif ()
439endfunction ()
440
441cmake_policy(POP)
function vtk_module_wrap_java()
Wrap a set of modules for use in Java.