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