VTK  9.2.6
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 
14 This function generates the wrapped sources for a module. It places the list of
15 generated source files and Java source files in variables named in the second
16 and third arguments, respectively.
17 
18 ~~~
19 _vtk_module_wrap_java_sources(<module> <sources> <classes>)
20 ~~~
21 #]==]
22 
23 cmake_policy(PUSH)
24 cmake_policy(SET CMP0053 NEW)
25 
26 function (_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)
182 endfunction ()
183 
184 #[==[
185 @ingroup module-impl
186 @brief Generate a JNI library for a set of modules
187 
188 A single JNI library may consist of the Java wrappings of multiple modules.
189 This is useful for kit-based builds where the modules part of the same kit
190 belong to the same JNI library as well.
191 
192 ~~~
193 _vtk_module_wrap_java_library(<name> <module>...)
194 ~~~
195 
196 The first argument is the name of the JNI library. The remaining arguments are
197 modules to include in the JNI library.
198 
199 The remaining information it uses is assumed to be provided by the
200 @ref vtk_module_wrap_java function.
201 #]==]
202 function (_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)
308 endfunction ()
309 
310 #[==[
311 @ingroup module-wrapping-java
312 @brief Wrap a set of modules for use in Java
313 
314 ~~~
315 vtk_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 
344 For each wrapped module, a `<module>Java` target will be created. These targets
345 will have a `_vtk_module_java_files` property which is the list of generated
346 Java source files for that target.
347 
348 For dependency purposes, the `<module>Java-java-sources` target may also be
349 used.
350 #]==]
351 function (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 ()
439 endfunction ()
440 
441 cmake_policy(POP)