VTK  9.2.6
vtkModuleWrapPython.cmake
Go to the documentation of this file.
1 #[==[
2 @defgroup module-wrapping-python Module Python CMake APIs
3 #]==]
4 
5 #[==[
6 @file vtkModuleWrapPython.cmake
7 @brief APIs for wrapping modules for Python
8 
9 @section python-wrapping-limitations Limitations
10 
11 Known limitations include:
12 
13  - Shared Python modules only really support shared builds of modules. VTK
14  does not provide mangling facilities for itself, so statically linking VTK
15  into its Python modules precludes using VTK's C++ interface anywhere else
16  within the Python environment.
17  - Only supports CPython. Other implementations are not supported by the
18  `VTK::WrapPython` executable.
19  - Links directly to a Python library. See the `VTK::Python` module for more
20  details.
21 #]==]
22 
23 #[==[
24 @ingroup module-wrapping-python
25 @brief Determine Python module destination
26 
27 Some projects may need to know where Python expects its modules to be placed in
28 the install tree (assuming a shared prefix). This function computes the default
29 and sets the passed variable to the value in the calling scope.
30 
31 ~~~
32 vtk_module_python_default_destination(<var>
33  [MAJOR_VERSION <major>])
34 ~~~
35 
36 By default, the destination is `${CMAKE_INSTALL_BINDIR}/Lib/site-packages` on
37 Windows and `${CMAKE_INSTALL_LIBDIR}/python<VERSION>/site-packages` otherwise.
38 
39 `<MAJOR_VERSION>` must be one of `2` or `3`. If not specified, it defaults to
40 the value of `${VTK_PYTHON_VERSION}`.
41 #]==]
42 
43 cmake_policy(PUSH)
44 cmake_policy(SET CMP0053 NEW)
45 
46 function (vtk_module_python_default_destination var)
47  cmake_parse_arguments(PARSE_ARGV 1 _vtk_module_python
48  ""
49  "MAJOR_VERSION"
50  "")
51 
52  if (_vtk_module_python_UNPARSED_ARGUMENTS)
53  message(FATAL_ERROR
54  "Unparsed arguments for vtk_module_python_default_destination: "
55  "${_vtk_module_python_UNPARSED_ARGUMENTS}")
56  endif ()
57 
58  if (NOT _vtk_module_python_MAJOR_VERSION)
59  if (NOT DEFINED VTK_PYTHON_VERSION)
60  message(FATAL_ERROR
61  "A major version of Python must be specified (or `VTK_PYTHON_VERSION` "
62  "be set).")
63  endif ()
64 
65  set(_vtk_module_python_MAJOR_VERSION "${VTK_PYTHON_VERSION}")
66  endif ()
67 
68  if (NOT _vtk_module_python_MAJOR_VERSION STREQUAL "2" AND
69  NOT _vtk_module_python_MAJOR_VERSION STREQUAL "3")
70  message(FATAL_ERROR
71  "Only Python2 and Python3 are supported right now.")
72  endif ()
73 
74  if (MSVC)
75  set(destination "${CMAKE_INSTALL_BINDIR}/Lib/site-packages")
76  else ()
77  if (NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR" OR
78  NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR")
79  find_package("Python${_vtk_module_python_MAJOR_VERSION}" QUIET COMPONENTS Development.Module)
80  endif ()
81 
82  if (Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR AND Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR)
83  set(_vtk_python_version_suffix "${Python${VTK_PYTHON_VERSION}_VERSION_MAJOR}.${Python${VTK_PYTHON_VERSION}_VERSION_MINOR}")
84  else ()
85  message(WARNING
86  "The version of Python is unknown; not using a versioned directory "
87  "for Python modules.")
88  set(_vtk_python_version_suffix)
89  endif ()
90  set(destination "${CMAKE_INSTALL_LIBDIR}/python${_vtk_python_version_suffix}/site-packages")
91  endif ()
92 
93  set("${var}" "${destination}" PARENT_SCOPE)
94 endfunction ()
95 
96 #[==[
97 @ingroup module-impl
98 @brief Generate sources for using a module's classes from Python
99 
100 This function generates the wrapped sources for a module. It places the list of
101 generated source files and classes in variables named in the second and third
102 arguments, respectively.
103 
104 ~~~
105 _vtk_module_wrap_python_sources(<module> <sources> <classes>)
106 ~~~
107 #]==]
108 function (_vtk_module_wrap_python_sources module sources classes)
109  _vtk_module_get_module_property("${module}"
110  PROPERTY "exclude_wrap"
111  VARIABLE _vtk_python_exclude_wrap)
112  if (_vtk_python_exclude_wrap)
113  return ()
114  endif ()
115 
116  file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python")
117 
118  set(_vtk_python_args_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python/${_vtk_python_library_name}-python.$<CONFIGURATION>.args")
119 
120  set(_vtk_python_hierarchy_depends "${module}")
121  _vtk_module_get_module_property("${module}"
122  PROPERTY "private_depends"
123  VARIABLE _vtk_python_private_depends)
124  list(APPEND _vtk_python_hierarchy_depends
125  ${_vtk_python_private_depends})
126  _vtk_module_get_module_property("${module}"
127  PROPERTY "optional_depends"
128  VARIABLE _vtk_python_optional_depends)
129  foreach (_vtk_python_optional_depend IN LISTS _vtk_python_optional_depends)
130  if (TARGET "${_vtk_python_optional_depend}")
131  list(APPEND _vtk_python_hierarchy_depends
132  "${_vtk_python_optional_depend}")
133  endif ()
134  endforeach ()
135 
136  set(_vtk_python_command_depends)
137  foreach (_vtk_python_hierarchy_depend IN LISTS _vtk_python_hierarchy_depends)
138  _vtk_module_get_module_property("${_vtk_python_hierarchy_depend}"
139  PROPERTY "hierarchy"
140  VARIABLE _vtk_python_hierarchy_file)
141  if (_vtk_python_hierarchy_file)
142  list(APPEND _vtk_python_hierarchy_files "${_vtk_python_hierarchy_file}")
143  get_property(_vtk_python_is_imported
144  TARGET "${_vtk_python_hierarchy_depend}"
145  PROPERTY "IMPORTED")
146  if (_vtk_python_is_imported OR CMAKE_GENERATOR MATCHES "Ninja")
147  list(APPEND _vtk_python_command_depends "${_vtk_python_hierarchy_file}")
148  else ()
149  _vtk_module_get_module_property("${_vtk_python_hierarchy_depend}"
150  PROPERTY "library_name"
151  VARIABLE _vtk_python_hierarchy_library_name)
152  if (TARGET "${_vtk_python_hierarchy_library_name}-hierarchy")
153  list(APPEND _vtk_python_command_depends "${_vtk_python_hierarchy_library_name}-hierarchy")
154  else ()
155  message(FATAL_ERROR
156  "The ${_vtk_python_hierarchy_depend} hierarchy file is attached to a non-imported target "
157  "and a hierarchy target (${_vtk_python_hierarchy_library_name}-hierarchy) is "
158  "missing.")
159  endif ()
160  endif ()
161  endif ()
162  endforeach ()
163 
164  set(_vtk_python_genex_compile_definitions
165  "$<TARGET_PROPERTY:${_vtk_python_target_name},COMPILE_DEFINITIONS>")
166  set(_vtk_python_genex_include_directories
167  "$<TARGET_PROPERTY:${_vtk_python_target_name},INCLUDE_DIRECTORIES>")
168  file(GENERATE
169  OUTPUT "${_vtk_python_args_file}"
170  CONTENT "$<$<BOOL:${_vtk_python_genex_compile_definitions}>:\n-D\'$<JOIN:${_vtk_python_genex_compile_definitions},\'\n-D\'>\'>\n
171 $<$<BOOL:${_vtk_python_genex_include_directories}>:\n-I\'$<JOIN:${_vtk_python_genex_include_directories},\'\n-I\'>\'>\n
172 $<$<BOOL:${_vtk_python_hierarchy_files}>:\n--types \'$<JOIN:${_vtk_python_hierarchy_files},\'\n--types \'>\'>\n")
173 
174  set(_vtk_python_sources)
175 
176  # Get the list of public headers from the module.
177  _vtk_module_get_module_property("${module}"
178  PROPERTY "headers"
179  VARIABLE _vtk_python_headers)
180  set(_vtk_python_classes)
181  foreach (_vtk_python_header IN LISTS _vtk_python_headers)
182  # Assume the class name matches the basename of the header. This is VTK
183  # convention.
184  get_filename_component(_vtk_python_basename "${_vtk_python_header}" NAME_WE)
185  list(APPEND _vtk_python_classes
186  "${_vtk_python_basename}")
187 
188  set(_vtk_python_source_output
189  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python/${_vtk_python_basename}Python.cxx")
190  list(APPEND _vtk_python_sources
191  "${_vtk_python_source_output}")
192 
193  set(_vtk_python_wrap_target "VTK::WrapPython")
194  set(_vtk_python_macros_args)
195  if (TARGET VTKCompileTools::WrapPython)
196  set(_vtk_python_wrap_target "VTKCompileTools::WrapPython")
197  if (TARGET VTKCompileTools_macros)
198  list(APPEND _vtk_python_command_depends
199  "VTKCompileTools_macros")
200  list(APPEND _vtk_python_macros_args
201  -undef
202  -imacros "${_VTKCompileTools_macros_file}")
203  endif ()
204  endif ()
205 
206  add_custom_command(
207  OUTPUT "${_vtk_python_source_output}"
208  COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR}
209  "$<TARGET_FILE:${_vtk_python_wrap_target}>"
210  "@${_vtk_python_args_file}"
211  -o "${_vtk_python_source_output}"
212  "${_vtk_python_header}"
213  ${_vtk_python_macros_args}
214  IMPLICIT_DEPENDS
215  CXX "${_vtk_python_header}"
216  COMMENT "Generating Python wrapper sources for ${_vtk_python_basename}"
217  DEPENDS
218  "${_vtk_python_header}"
219  "${_vtk_python_args_file}"
220  "$<TARGET_FILE:${_vtk_python_wrap_target}>"
221  ${_vtk_python_command_depends})
222  endforeach ()
223 
224  set("${sources}"
225  "${_vtk_python_sources}"
226  PARENT_SCOPE)
227  set("${classes}"
228  "${_vtk_python_classes}"
229  PARENT_SCOPE)
230 endfunction ()
231 
232 #[==[
233 @ingroup module-impl
234 @brief Generate a CPython library for a set of modules
235 
236 A Python module library may consist of the Python wrappings of multiple
237 modules. This is useful for kit-based builds where the modules part of the same
238 kit belong to the same Python module as well.
239 
240 ~~~
241 _vtk_module_wrap_python_library(<name> <module>...)
242 ~~~
243 
244 The first argument is the name of the Python module. The remaining arguments
245 are modules to include in the Python module.
246 
247 The remaining information it uses is assumed to be provided by the
248 @ref vtk_module_wrap_python function.
249 #]==]
250 function (_vtk_module_wrap_python_library name)
251  set(_vtk_python_library_sources)
252  set(_vtk_python_library_classes)
253  foreach (_vtk_python_module IN LISTS ARGN)
254  _vtk_module_get_module_property("${_vtk_python_module}"
255  PROPERTY "exclude_wrap"
256  VARIABLE _vtk_python_exclude_wrap)
257  if (_vtk_python_exclude_wrap)
258  continue ()
259  endif ()
260  _vtk_module_real_target(_vtk_python_target_name "${_vtk_python_module}")
261  _vtk_module_get_module_property("${_vtk_python_module}"
262  PROPERTY "library_name"
263  VARIABLE _vtk_python_library_name)
264 
265  # Wrap the module independently of the other VTK modules in the Python
266  # module.
267  _vtk_module_wrap_python_sources("${_vtk_python_module}" _vtk_python_sources _vtk_python_classes)
268  list(APPEND _vtk_python_library_sources
269  ${_vtk_python_sources})
270  list(APPEND _vtk_python_library_classes
271  ${_vtk_python_classes})
272 
273  # Make sure the module doesn't already have an associated Python package.
274  vtk_module_get_property("${_vtk_python_module}"
275  PROPERTY "INTERFACE_vtk_module_python_package"
276  VARIABLE _vtk_python_current_python_package)
277  if (DEFINED _vtk_python_current_python_package)
278  message(FATAL_ERROR
279  "It appears as though the ${_vtk_python_module} has already been "
280  "wrapped in Python in the ${_vtk_python_current_python_package} "
281  "package.")
282  endif ()
283  vtk_module_set_property("${_vtk_python_module}"
284  PROPERTY "INTERFACE_vtk_module_python_package"
285  VALUE "${_vtk_python_PYTHON_PACKAGE}")
286 
287  if (_vtk_python_INSTALL_HEADERS)
288  _vtk_module_export_properties(
289  BUILD_FILE "${_vtk_python_properties_build_file}"
290  INSTALL_FILE "${_vtk_python_properties_install_file}"
291  MODULE "${_vtk_python_module}"
292  PROPERTIES
293  # Export the wrapping hints file.
294  INTERFACE_vtk_module_python_package)
295  endif ()
296  endforeach ()
297 
298  # The foreach needs to be split so that dependencies are guaranteed to have
299  # the INTERFACE_vtk_module_python_package property set.
300  foreach (_vtk_python_module IN LISTS ARGN)
301  _vtk_module_get_module_property("${_vtk_python_module}"
302  PROPERTY "exclude_wrap"
303  VARIABLE _vtk_python_exclude_wrap)
304  if (_vtk_python_exclude_wrap)
305  continue ()
306  endif ()
307 
308  _vtk_module_get_module_property("${_vtk_python_module}"
309  PROPERTY "library_name"
310  VARIABLE _vtk_python_library_name)
311 
312  _vtk_module_get_module_property("${_vtk_python_module}"
313  PROPERTY "depends"
314  VARIABLE _vtk_python_module_depends)
315  set(_vtk_python_module_load_depends)
316  foreach (_vtk_python_module_depend IN LISTS _vtk_python_module_depends)
317  _vtk_module_get_module_property("${_vtk_python_module_depend}"
318  PROPERTY "exclude_wrap"
319  VARIABLE _vtk_python_module_depend_exclude_wrap)
320  if (_vtk_python_module_depend_exclude_wrap)
321  continue ()
322  endif ()
323 
324  _vtk_module_get_module_property("${_vtk_python_module_depend}"
325  PROPERTY "python_package"
326  VARIABLE _vtk_python_depend_module_package)
327  _vtk_module_get_module_property("${_vtk_python_module_depend}"
328  PROPERTY "library_name"
329  VARIABLE _vtk_python_depend_library_name)
330 
331  # XXX(kits): This doesn't work for kits.
332  list(APPEND _vtk_python_module_load_depends
333  "${_vtk_python_depend_module_package}.${_vtk_python_depend_library_name}")
334  endforeach ()
335 
336  if (_vtk_python_BUILD_STATIC)
337  # If static, we use .py modules that grab the contents from the baked-in modules.
338  set(_vtk_python_module_file
339  "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}/${_vtk_python_library_name}.py")
340  set(_vtk_python_module_contents
341  "from ${_vtk_python_import_prefix}${_vtk_python_library_name} import *\n")
342 
343  file(GENERATE
344  OUTPUT "${_vtk_python_module_file}"
345  CONTENT "${_vtk_python_module_contents}")
346 
347  # Set `python_modules` to provide the list of python files that go along with
348  # this module
349  _vtk_module_set_module_property("${_vtk_python_module}" APPEND
350  PROPERTY "python_modules"
351  VALUE "${_vtk_python_module_file}")
352  endif ()
353  endforeach ()
354 
355  if (NOT _vtk_python_library_sources)
356  return ()
357  endif ()
358 
359  set(_vtk_python_init_data_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}Python/${name}-init.data")
360 
361  file(GENERATE
362  OUTPUT "${_vtk_python_init_data_file}"
363  CONTENT "${_vtk_python_library_name}\n$<JOIN:${_vtk_python_classes},\n>\nDEPENDS\n$<JOIN:${_vtk_python_module_load_depends},\n>\n")
364 
365  set(_vtk_python_init_output
366  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}Python/${name}Init.cxx")
367  set(_vtk_python_init_impl_output
368  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}Python/${name}InitImpl.cxx")
369  list(APPEND _vtk_python_library_sources
370  "${_vtk_python_init_output}"
371  "${_vtk_python_init_impl_output}")
372 
373  set(_vtk_python_wrap_target "VTK::WrapPythonInit")
374  if (TARGET VTKCompileTools::WrapPythonInit)
375  set(_vtk_python_wrap_target "VTKCompileTools::WrapPythonInit")
376  endif ()
377 
378  if(_vtk_python_BUILD_STATIC)
379  set(additonal_options "${_vtk_python_import_prefix}")
380  endif()
381  add_custom_command(
382  OUTPUT "${_vtk_python_init_output}"
383  "${_vtk_python_init_impl_output}"
384  COMMAND "${_vtk_python_wrap_target}"
385  "${_vtk_python_init_data_file}"
386  "${_vtk_python_init_output}"
387  "${_vtk_python_init_impl_output}"
388  "${additonal_options}"
389  COMMENT "Generating the Python module initialization sources for ${name}"
390  DEPENDS
391  "${_vtk_python_init_data_file}"
392  "$<TARGET_FILE:${_vtk_python_wrap_target}>")
393 
394  if (_vtk_python_BUILD_STATIC)
395  set(_vtk_python_module_header_file
396  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}/static_python/${name}.h")
397  set(_vtk_python_module_header_content
398 "#ifndef ${name}_h
399 #define ${name}_h
400 
401 #include <vtkPython.h>
402 
403 #ifdef __cplusplus
404 extern \"C\" {
405 #endif
406 #if PY_VERSION_HEX < 0x03000000
407 extern void init${_vtk_python_library_name}();
408 #else
409 extern PyObject* PyInit_${_vtk_python_library_name}();
410 #endif
411 #ifdef __cplusplus
412 }
413 #endif
414 
415 #endif
416 ")
417 
418  file(GENERATE
419  OUTPUT "${_vtk_python_module_header_file}"
420  CONTENT "${_vtk_python_module_header_content}")
421  # XXX(cmake): Why is this necessary? One would expect that `file(GENERATE)`
422  # would do this automatically.
423  set_property(SOURCE "${_vtk_python_module_header_file}"
424  PROPERTY
425  GENERATED 1)
426 
427  add_library("${name}" STATIC
428  ${_vtk_python_library_sources}
429  "${_vtk_python_module_header_file}")
430  target_include_directories("${name}"
431  INTERFACE
432  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}/static_python>")
433  target_link_libraries("${name}"
434  PUBLIC
435  VTK::Python)
436 
437  if (_vtk_python_UTILITY_TARGET)
438  target_link_libraries("${name}"
439  PRIVATE
440  "${_vtk_python_UTILITY_TARGET}")
441  endif ()
442 
443  set_property(TARGET "${name}"
444  PROPERTY
445  LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_python_STATIC_MODULE_DESTINATION}")
446  else ()
447  add_library("${name}" MODULE
448  ${_vtk_python_library_sources})
449  if (WIN32 AND NOT CYGWIN)
450  # This is enabled explicitly by the USE_DEBUG_SUFFIX argument because
451  # there's no reliable way to detect whether we're using a debug build of
452  # Python or not.
453  #
454  # The proper fix is to dig around and ask the backing `PythonN::Python`
455  # target used by `VTK::Python` for its properties to find out, per
456  # configuration, whether it is a debug build. If it is, add the postfix
457  # (regardless of VTK's build type). Otherwise, no postfix.
458  if (_vtk_python_USE_DEBUG_SUFFIX)
459  set_property(TARGET "${name}"
460  APPEND_STRING
461  PROPERTY
462  DEBUG_POSTFIX "_d")
463  endif ()
464  set_property(TARGET "${name}"
465  PROPERTY
466  SUFFIX ".pyd")
467  endif ()
468  set_property(TARGET "${name}"
469  PROPERTY
470  LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}")
471  get_property(_vtk_python_is_multi_config GLOBAL
472  PROPERTY GENERATOR_IS_MULTI_CONFIG)
473  if (_vtk_python_is_multi_config)
474  # XXX(MultiNinja): This isn't going to work in general since MultiNinja
475  # will error about overlapping output paths.
476  foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
477  string(TOUPPER "${_vtk_python_config}" _vtk_python_config_upper)
478  set_property(TARGET "${name}"
479  PROPERTY
480  "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}")
481  endforeach ()
482  endif ()
483 
484  if (_vtk_python_UTILITY_TARGET)
485  target_link_libraries("${name}"
486  PRIVATE
487  "${_vtk_python_UTILITY_TARGET}")
488  endif ()
489 
490  set_target_properties("${name}"
491  PROPERTIES
492  PREFIX ""
493  OUTPUT_NAME "${_vtk_python_library_name}"
494  ARCHIVE_OUTPUT_NAME "${name}")
495  endif ()
496 
497  vtk_module_autoinit(
498  MODULES ${ARGN}
499  TARGETS "${name}")
500 
501  # The wrapper code will expand PYTHON_PACKAGE as needed
502  target_compile_definitions("${name}"
503  PRIVATE
504  "-DPYTHON_PACKAGE=\"${_vtk_python_PYTHON_PACKAGE}\"")
505 
506  target_link_libraries("${name}"
507  PRIVATE
508  ${ARGN}
509  VTK::WrappingPythonCore
510  VTK::Python)
511 
512  set(_vtk_python_export)
513  if (_vtk_python_INSTALL_EXPORT)
514  list(APPEND _vtk_python_export
515  EXPORT "${_vtk_python_INSTALL_EXPORT}")
516  endif ()
517 
518  set(_vtk_python_wrap_component "${_vtk_python_COMPONENT}")
519  if (_vtk_python_TARGET_SPECIFIC_COMPONENTS)
520  string(PREPEND _vtk_python_wrap_component "${name}-")
521  endif ()
522 
523  install(
524  TARGETS "${name}"
525  ${_vtk_python_export}
526  COMPONENT "${_vtk_python_wrap_component}"
527  RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
528  LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
529  ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}")
530 endfunction ()
531 
532 #[==[
533 @ingroup module-wrapping-python
534 @brief Wrap a set of modules for use in Python
535 
536 ~~~
537 vtk_module_wrap_python(
538  MODULES <module>...
539  [TARGET <target>]
540  [WRAPPED_MODULES <varname>]
541 
542  [BUILD_STATIC <ON|OFF>]
543  [INSTALL_HEADERS <ON|OFF>]
544  [BUILD_PYI_FILES <ON|OFF>]
545 
546  [DEPENDS <target>...]
547  [UTILITY_TARGET <target>]
548 
549  [MODULE_DESTINATION <destination>]
550  [STATIC_MODULE_DESTINATION <destination>]
551  [CMAKE_DESTINATION <destination>]
552  [LIBRARY_DESTINATION <destination>]
553 
554  [PYTHON_PACKAGE <package>]
555  [SOABI <soabi>]
556  [USE_DEBUG_SUFFIX <ON|OFF>]
557 
558  [INSTALL_EXPORT <export>]
559  [COMPONENT <component>])
560  [TARGET_SPECIFIC_COMPONENTS <ON|OFF>]
561 ~~~
562 
563  * `MODULES`: (Required) The list of modules to wrap.
564  * `TARGET`: (Recommended) The target to create which represents all wrapped
565  Python modules. This is mostly useful when supporting static Python modules
566  in order to add the generated modules to the built-in table.
567  * `WRAPPED_MODULES`: (Recommended) Not all modules are wrappable. This
568  variable will be set to contain the list of modules which were wrapped.
569  These modules will have a `INTERFACE_vtk_module_python_package` property
570  set on them which is the name that should be given to `import` statements
571  in Python code.
572  * `BUILD_STATIC`: Defaults to `${BUILD_SHARED_LIBS}`. Note that shared
573  modules with a static build is not completely supported. For static Python
574  module builds, a header named `<TARGET>.h` will be available with a
575  function `void <TARGET>_load()` which will add all Python modules created
576  by this call to the imported module table. For shared Python module builds,
577  the same function is provided, but it is a no-op.
578  * `INSTALL_HEADERS` (Defaults to `ON`): If unset, CMake properties will not
579  be installed.
580  * `BUILD_PYI_FILES` (Defaults to `OFF`): If set, `.pyi` files will be built
581  and installed for the generated modules.
582  * `TARGET_SPECIFIC_COMPONENTS` (Defaults to `OFF`): If set, prepend the
583  output target name to the install component (`<TARGET>-<COMPONENT>`).
584  * `DEPENDS`: This is list of other Python modules targets i.e. targets
585  generated from previous calls to `vtk_module_wrap_python` that this new
586  target depends on. This is used when `BUILD_STATIC` is true to ensure that
587  the `void <TARGET>_load()` is correctly called for each of the dependencies.
588  * `UTILITY_TARGET`: If specified, all libraries made by the Python wrapping
589  will link privately to this target. This may be used to add compile flags
590  to the Python libraries.
591  * `MODULE_DESTINATION`: Modules will be placed in this location in the
592  build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
593  currently does not. See `vtk_module_python_default_destination` for the
594  default value.
595  * `STATIC_MODULE_DESTINATION`: Defaults to `${CMAKE_INSTALL_LIBDIR}`. This
596  default may change in the future since the best location for these files is
597  not yet known. Static libraries containing Python code will be installed to
598  the install tree under this path.
599  * `CMAKE_DESTINATION`: (Required if `INSTALL_HEADERS` is `ON`) Where to
600  install Python-related module property CMake files.
601  * `LIBRARY_DESTINATION` (Recommended): If provided, dynamic loader
602  information will be added to modules for loading dependent libraries.
603  * `PYTHON_PACKAGE`: (Recommended) All generated modules will be added to this
604  Python package. The format is in Python syntax (e.g.,
605  `package.subpackage`).
606  * `SOABI`: (Required for wheel support): If given, generate libraries with
607  the SOABI tag in the module filename.
608  * `USE_DEBUG_SUFFIX` (Defaults to `OFF`): If `ON`, Windows modules will have
609  a `_d` suffix appended to the module name. This is intended for use with
610  debug Python builds.
611  * `INSTALL_EXPORT`: If provided, static installs will add the installed
612  libraries to the provided export set.
613  * `COMPONENT`: Defaults to `python`. All install rules created by this
614  function will use this installation component.
615 #]==]
616 function (vtk_module_wrap_python)
617  cmake_parse_arguments(PARSE_ARGV 0 _vtk_python
618  ""
619  "MODULE_DESTINATION;STATIC_MODULE_DESTINATION;LIBRARY_DESTINATION;PYTHON_PACKAGE;BUILD_STATIC;INSTALL_HEADERS;INSTALL_EXPORT;TARGET_SPECIFIC_COMPONENTS;TARGET;COMPONENT;WRAPPED_MODULES;CMAKE_DESTINATION;SOABI;USE_DEBUG_SUFFIX;UTILITY_TARGET;BUILD_PYI_FILES"
620  "DEPENDS;MODULES")
621 
622  if (_vtk_python_UNPARSED_ARGUMENTS)
623  message(FATAL_ERROR
624  "Unparsed arguments for vtk_module_wrap_python: "
625  "${_vtk_python_UNPARSED_ARGUMENTS}")
626  endif ()
627 
628  if (NOT _vtk_python_MODULES)
629  message(WARNING
630  "No modules were requested for Python wrapping.")
631  return ()
632  endif ()
633 
634  _vtk_module_split_module_name("${_vtk_python_TARGET}" _vtk_python)
635 
636  set(_vtk_python_depends)
637  foreach (_vtk_python_depend IN LISTS _vtk_python_DEPENDS)
638  _vtk_module_split_module_name("${_vtk_python_depend}" _vtk_python_depends)
639  list(APPEND _vtk_python_depends
640  "${_vtk_python_depends_TARGET_NAME}")
641  endforeach ()
642 
643  if (NOT DEFINED _vtk_python_MODULE_DESTINATION)
644  vtk_module_python_default_destination(_vtk_python_MODULE_DESTINATION)
645  endif ()
646 
647  if (NOT DEFINED _vtk_python_INSTALL_HEADERS)
648  set(_vtk_python_INSTALL_HEADERS ON)
649  endif ()
650 
651  if (NOT DEFINED _vtk_python_BUILD_PYI_FILES)
652  set(_vtk_python_BUILD_PYI_FILES OFF)
653  endif ()
654 
655  if (NOT DEFINED _vtk_python_TARGET_SPECIFIC_COMPONENTS)
656  set(_vtk_python_TARGET_SPECIFIC_COMPONENTS OFF)
657  endif ()
658 
659  if (NOT DEFINED _vtk_python_USE_DEBUG_SUFFIX)
660  set(_vtk_python_USE_DEBUG_SUFFIX OFF)
661  endif ()
662 
663  if (_vtk_python_SOABI)
664  get_property(_vtk_python_is_multi_config GLOBAL
665  PROPERTY GENERATOR_IS_MULTI_CONFIG)
666  if (_vtk_python_is_multi_config)
667  foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
668  string(TOUPPER "${_vtk_python_config}" _vtk_python_upper_config)
669  set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
670  ".${_vtk_python_SOABI}")
671  endforeach ()
672  else ()
673  string(TOUPPER "${CMAKE_BUILD_TYPE}" _vtk_python_upper_config)
674  set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
675  ".${_vtk_python_SOABI}")
676  endif ()
677  endif ()
678 
679  if (_vtk_python_INSTALL_HEADERS AND NOT DEFINED _vtk_python_CMAKE_DESTINATION)
680  message(FATAL_ERROR
681  "No CMAKE_DESTINATION set, but headers from the Python wrapping were "
682  "requested for install and the CMake files are required to work with "
683  "them.")
684  endif ()
685 
686  if (NOT DEFINED _vtk_python_BUILD_STATIC)
687  if (BUILD_SHARED_LIBS)
688  set(_vtk_python_BUILD_STATIC OFF)
689  else ()
690  set(_vtk_python_BUILD_STATIC ON)
691  endif ()
692  else ()
693  if (NOT _vtk_python_BUILD_STATIC AND NOT BUILD_SHARED_LIBS)
694  message(WARNING
695  "Building shared Python modules against static VTK modules only "
696  "supports consuming the VTK modules via their Python interfaces due "
697  "to the lack of support for an SDK to use the same static libraries.")
698  endif ()
699  endif ()
700 
701  if (NOT DEFINED _vtk_python_STATIC_MODULE_DESTINATION)
702  # TODO: Is this correct?
703  set(_vtk_python_STATIC_MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}")
704  endif ()
705 
706  if (NOT DEFINED _vtk_python_COMPONENT)
707  set(_vtk_python_COMPONENT "python")
708  endif ()
709 
710  if (NOT _vtk_python_PYTHON_PACKAGE)
711  message(FATAL_ERROR
712  "No `PYTHON_PACKAGE` was given; Python modules must be placed into a "
713  "package.")
714  endif ()
715  string(REPLACE "." "/" _vtk_python_package_path "${_vtk_python_PYTHON_PACKAGE}")
716 
717  if(_vtk_python_BUILD_STATIC)
718  # When doing static builds we want the statically initialized built-ins to be
719  # used. It is unclear in the Python-C API how to construct `namespace.module`
720  # so instead at the C++ level we import "namespace_module" during startup
721  # and than the python modules moving those imports into the correct python
722  # module.
723  string(REPLACE "." "_" _vtk_python_import_prefix "${_vtk_python_PYTHON_PACKAGE}_")
724  else()
725  # We are building dynamic libraries therefore the prefix is simply '.'
726  set(_vtk_python_import_prefix ".")
727  endif()
728 
729  _vtk_module_check_destinations(_vtk_python_
730  MODULE_DESTINATION
731  STATIC_MODULE_DESTINATION
732  CMAKE_DESTINATION
733  LIBRARY_DESTINATION)
734 
735  if (_vtk_python_INSTALL_HEADERS)
736  set(_vtk_python_properties_filename "${_vtk_python_PYTHON_PACKAGE}-vtk-python-module-properties.cmake")
737  set(_vtk_python_properties_install_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/${_vtk_python_properties_filename}.install")
738  set(_vtk_python_properties_build_file "${CMAKE_BINARY_DIR}/${_vtk_python_CMAKE_DESTINATION}/${_vtk_python_properties_filename}")
739 
740  file(WRITE "${_vtk_python_properties_build_file}")
741  file(WRITE "${_vtk_python_properties_install_file}")
742  endif ()
743 
744  if (DEFINED _vtk_python_LIBRARY_DESTINATION)
745  # Set up rpaths
746  set(CMAKE_BUILD_RPATH_USE_ORIGIN 1)
747  if (UNIX)
748  file(RELATIVE_PATH _vtk_python_relpath
749  "/prefix/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
750  "/prefix/${_vtk_python_LIBRARY_DESTINATION}")
751 
752  if (APPLE)
753  set(_vtk_python_origin_stem "@loader_path")
754  else ()
755  set(_vtk_python_origin_stem "$ORIGIN")
756  endif()
757 
758  list(APPEND CMAKE_INSTALL_RPATH
759  "${_vtk_python_origin_stem}/${_vtk_python_relpath}")
760  endif ()
761  endif ()
762 
763  set(_vtk_python_sorted_modules ${_vtk_python_MODULES})
764  foreach (_vtk_python_module IN LISTS _vtk_python_MODULES)
765  _vtk_module_get_module_property("${_vtk_python_module}"
766  PROPERTY "depends"
767  VARIABLE "_vtk_python_${_vtk_python_module}_depends")
768  endforeach ()
769  vtk_topological_sort(_vtk_python_sorted_modules "_vtk_python_" "_depends")
770 
771  set(_vtk_python_sorted_modules_filtered)
772  foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules)
773  if (_vtk_python_module IN_LIST _vtk_python_MODULES)
774  list(APPEND _vtk_python_sorted_modules_filtered
775  "${_vtk_python_module}")
776  endif ()
777  endforeach ()
778 
779  set(_vtk_python_headers_component "development")
780  set(_vtk_python_component "${_vtk_python_COMPONENT}")
781  if (_vtk_python_TARGET_SPECIFIC_COMPONENTS)
782  string(PREPEND _vtk_python_headers_component "${_vtk_python_TARGET_NAME}-")
783  string(PREPEND _vtk_python_component "${_vtk_python_TARGET_NAME}-")
784  endif ()
785 
786  # Disable CMake's automoc support for these targets.
787  set(CMAKE_AUTOMOC 0)
788  set(CMAKE_AUTORCC 0)
789  set(CMAKE_AUTOUIC 0)
790 
791  set(_vtk_python_all_modules)
792  set(_vtk_python_all_wrapped_modules)
793  foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
794  _vtk_module_get_module_property("${_vtk_python_module}"
795  PROPERTY "library_name"
796  VARIABLE _vtk_python_library_name)
797  _vtk_module_wrap_python_library("${_vtk_python_library_name}Python" "${_vtk_python_module}")
798 
799  if (TARGET "${_vtk_python_library_name}Python")
800  list(APPEND _vtk_python_all_modules
801  "${_vtk_python_library_name}Python")
802  list(APPEND _vtk_python_all_wrapped_modules
803  "${_vtk_python_module}")
804  endif ()
805  endforeach ()
806 
807  if (NOT _vtk_python_all_modules)
808  message(FATAL_ERROR
809  "No modules given could be wrapped.")
810  endif ()
811 
812  if (_vtk_python_INSTALL_HEADERS)
813  install(
814  FILES "${_vtk_python_properties_install_file}"
815  DESTINATION "${_vtk_python_CMAKE_DESTINATION}"
816  RENAME "${_vtk_python_properties_filename}"
817  COMPONENT "${_vtk_python_headers_component}")
818  endif ()
819 
820  if (DEFINED _vtk_python_WRAPPED_MODULES)
821  set("${_vtk_python_WRAPPED_MODULES}"
822  "${_vtk_python_all_wrapped_modules}"
823  PARENT_SCOPE)
824  endif ()
825 
826  if (_vtk_python_TARGET)
827  add_library("${_vtk_python_TARGET_NAME}" INTERFACE)
828  target_include_directories("${_vtk_python_TARGET_NAME}"
829  INTERFACE
830  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python>")
831  target_link_libraries("${_vtk_python_TARGET_NAME}"
832  INTERFACE
833  ${_vtk_python_DEPENDS})
834  if (NOT _vtk_python_TARGET STREQUAL _vtk_python_TARGET_NAME)
835  add_library("${_vtk_python_TARGET}" ALIAS
836  "${_vtk_python_TARGET_NAME}")
837  endif ()
838 
839  if (_vtk_python_INSTALL_EXPORT)
840  install(
841  TARGETS "${_vtk_python_TARGET_NAME}"
842  EXPORT "${_vtk_python_INSTALL_EXPORT}"
843  COMPONENT "${_vtk_python_headers_component}")
844  endif ()
845 
846  set(_vtk_python_all_modules_include_file
847  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_TARGET_NAME}.h")
848  set(_vtk_python_all_modules_include_content
849  "#ifndef ${_vtk_python_TARGET_NAME}_h\n#define ${_vtk_python_TARGET_NAME}_h\n")
850 
851  if (_vtk_python_BUILD_STATIC)
852  foreach (_vtk_python_module IN LISTS _vtk_python_all_modules)
853  string(APPEND _vtk_python_all_modules_include_content
854  "#include \"${_vtk_python_module}.h\"\n")
855  endforeach ()
856  endif ()
857 
858  foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
859  string(APPEND _vtk_python_all_modules_include_content
860  "#include \"${_vtk_python_depend}.h\"\n")
861  endforeach ()
862 
863  string(APPEND _vtk_python_all_modules_include_content
864 "#if PY_VERSION_HEX < 0x03000000
865 #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, init ## module)
866 #define PY_IMPORT(module) init ## module();
867 #else
868 #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, PyInit_ ## module)
869 #define PY_IMPORT(module) { \\
870  PyObject* var_ ## module = PyInit_ ## module(); \\
871  PyDict_SetItemString(PyImport_GetModuleDict(), \"${_vtk_python_import_prefix}\" #module,var_ ## module); \\
872  Py_DECREF(var_ ## module); }
873 #endif
874 
875 #define PY_APPEND_INIT_OR_IMPORT(module, do_import) \\
876  if (do_import) { PY_IMPORT(module); } else { PY_APPEND_INIT(module); }
877 
878 static void ${_vtk_python_TARGET_NAME}_load() {\n")
879 
880  foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
881  string(APPEND _vtk_python_all_modules_include_content
882  " ${_vtk_python_depend}_load();\n")
883  endforeach ()
884 
885  if (_vtk_python_BUILD_STATIC)
886  string(APPEND _vtk_python_all_modules_include_content
887  " int do_import = Py_IsInitialized();\n")
888  foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
889  _vtk_module_get_module_property("${_vtk_python_module}"
890  PROPERTY "library_name"
891  VARIABLE _vtk_python_library_name)
892  if (TARGET "${_vtk_python_library_name}Python")
893  string(APPEND _vtk_python_all_modules_include_content
894  " PY_APPEND_INIT_OR_IMPORT(${_vtk_python_library_name}, do_import);\n")
895  endif ()
896  endforeach ()
897  endif ()
898 
899  string(APPEND _vtk_python_all_modules_include_content
900  "}\n#undef PY_APPEND_INIT\n#undef PY_IMPORT\n#undef PY_APPEND_INIT_OR_IMPORT\n#endif\n")
901 
902  # TODO: Install this header.
903  file(GENERATE
904  OUTPUT "${_vtk_python_all_modules_include_file}"
905  CONTENT "${_vtk_python_all_modules_include_content}")
906 
907  if (_vtk_python_BUILD_STATIC)
908  # TODO: Install these targets.
909  target_link_libraries("${_vtk_python_TARGET_NAME}"
910  INTERFACE
911  ${_vtk_python_all_modules})
912  endif ()
913 
914  if (_vtk_python_BUILD_STATIC)
915  # Next, we generate a Python module that can be imported to import any
916  # static artifacts e.g. all wrapping Python modules in static builds,
917  # (eventually, frozen modules etc.)
918  string(REPLACE "." "_" _vtk_python_static_importer_name "_${_vtk_python_PYTHON_PACKAGE}_static")
919  set(_vtk_python_static_importer_file
920  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_static_importer_name}.c")
921  set(_vtk_python_static_importer_content "// generated file, do not edit!
922 #include <vtkPython.h>
923 #include \"${_vtk_python_TARGET_NAME}.h\"
924 
925  static PyMethodDef Py${_vtk_python_static_importer_name}_Methods[] = {
926  {NULL, NULL, 0, NULL}};
927 #if PY_VERSION_HEX >= 0x03000000
928  static PyModuleDef ${_vtk_python_static_importer_name}Module = {
929  PyModuleDef_HEAD_INIT,
930  \"${_vtk_python_static_importer_name}\", // m_name
931  \"module to import static components for ${_vtk_python_TARGET_NAME}\", // m_doc
932  0, // m_size
933  Py${_vtk_python_static_importer_name}_Methods, // m_methods
934  NULL, // m_reload
935  NULL, // m_traverse
936  NULL, // m_clear
937  NULL // m_free
938  };
939 #endif
940 
941 #if PY_VERSION_HEX >= 0x03000000
942  PyMODINIT_FUNC PyInit_${_vtk_python_static_importer_name}(void)
943 #else
944  PyMODINIT_FUNC init${_vtk_python_static_importer_name}(void)
945 #endif
946  {
947  // since this gets called after `Py_Initialize`, this will import the static
948  // modules and not just update the init table.
949  ${_vtk_python_TARGET_NAME}_load();
950 #if PY_VERSION_HEX >= 0x03000000
951  return PyModule_Create(&${_vtk_python_static_importer_name}Module);
952 #else
953  Py_InitModule(\"${_vtk_python_static_importer_name}\", Py${_vtk_python_static_importer_name}_Methods);
954 #endif
955  }\n")
956 
957  # TODO: Install this header.
958  file(GENERATE
959  OUTPUT "${_vtk_python_static_importer_file}"
960  CONTENT "${_vtk_python_static_importer_content}")
961 
962  add_library("${_vtk_python_static_importer_name}" MODULE
963  ${_vtk_python_static_importer_file})
964  if (WIN32 AND NOT CYGWIN)
965  set_property(TARGET "${_vtk_python_static_importer_name}"
966  PROPERTY
967  SUFFIX ".pyd")
968  endif()
969  set_property(TARGET "${_vtk_python_static_importer_name}"
970  PROPERTY
971  LIBRARY_OUTPUT_DIRECTORY "${_vtk_python_MODULE_DESTINATION}")
972  get_property(_vtk_python_is_multi_config GLOBAL
973  PROPERTY GENERATOR_IS_MULTI_CONFIG)
974  if (_vtk_python_is_multi_config)
975  # XXX(MultiNinja): This isn't going to work in general since MultiNinja
976  # will error about overlapping output paths.
977  foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
978  string(TOUPPER "${_vtk_python_config}" _vtk_python_config_upper)
979  set_property(TARGET "${_vtk_python_static_importer_name}"
980  PROPERTY
981  "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}")
982  endforeach ()
983  endif ()
984  set_property(TARGET "${_vtk_python_static_importer_name}"
985  PROPERTY
986  PREFIX "")
987  target_link_libraries("${_vtk_python_static_importer_name}"
988  PRIVATE
989  ${_vtk_python_TARGET_NAME}
990  VTK::WrappingPythonCore
991  VTK::Python)
992 
993  install(
994  TARGETS "${_vtk_python_static_importer_name}"
995  COMPONENT "${_vtk_python_component}"
996  RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}"
997  LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}"
998  ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}")
999  endif () # if (_vtk_python_BUILD_STATIC)
1000 
1001  # convert package "x.y" into "x/y" to access its contents on the filesystem
1002  string(REPLACE "." "/" _vtk_python_package_dir "${_vtk_python_PYTHON_PACKAGE}")
1003 
1004  if (_vtk_python_BUILD_PYI_FILES)
1005  set(_vtk_python_pyi_files)
1006  set(_vtk_python_modules)
1007  set(_vtk_python_module_targets)
1008  foreach (_vtk_python_module IN LISTS _vtk_python_all_wrapped_modules)
1009  get_property(_vtk_python_library_name
1010  TARGET "${_vtk_python_module}"
1011  PROPERTY "INTERFACE_vtk_module_library_name")
1012  list(APPEND _vtk_python_pyi_files
1013  "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_dir}/${_vtk_python_library_name}.pyi")
1014  list(APPEND _vtk_python_modules "${_vtk_python_library_name}")
1015  if (TARGET "${_vtk_python_library_name}Python")
1016  list(APPEND _vtk_python_module_targets "${_vtk_python_library_name}Python")
1017  endif ()
1018  endforeach ()
1019 
1020  if (TARGET VTK::vtkpython)
1021  set(_vtk_python_exe $<TARGET_FILE:VTK::vtkpython>)
1022  else ()
1023  set(_vtk_python_exe "${Python3_EXECUTABLE}")
1024  endif ()
1025 
1026  # XXX(python2): Remove this conditional
1027  if (NOT VTK_PYTHON_VERSION STREQUAL "2")
1028  add_custom_command(
1029  OUTPUT ${_vtk_python_pyi_files}
1030  COMMAND "${_vtk_python_exe}"
1031  -m vtkmodules.generate_pyi
1032  -p "${_vtk_python_PYTHON_PACKAGE}"
1033  -o "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_dir}"
1034  ${_vtk_python_modules}
1035  WORKING_DIRECTORY
1036  "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}"
1037  DEPENDS ${_vtk_python_module_targets}
1038  ${_vtk_python_static_importer_name}
1039  "${_vtk_pyi_script}"
1040  COMMENT "Creating .pyi files for ${_vtk_python_TARGET_NAME}")
1041 
1042  install(
1043  FILES ${_vtk_python_pyi_files}
1044  DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_dir}"
1045  COMPONENT "${_vtk_python_component}")
1046 
1047  add_custom_target("${_vtk_python_TARGET_NAME}_pyi" ALL
1048  DEPENDS ${_vtk_python_pyi_files})
1049  endif ()
1050  endif ()
1051  endif ()
1052 endfunction ()
1053 
1054 #[==[
1055 @ingroup module-wrapping-python
1056 @brief Install Python packages with a module
1057 
1058 Some modules may have associated Python code. This function should be used to
1059 install them.
1060 
1061 ~~~
1062 vtk_module_add_python_package(<module>
1063  PACKAGE <package>
1064  FILES <files>...
1065  [MODULE_DESTINATION <destination>]
1066  [COMPONENT <component>])
1067 ~~~
1068 
1069 The `<module>` argument must match the associated VTK module that the package
1070 is with. Each package is independent and should be installed separately. That
1071 is, `package` and `package.subpackage` should each get their own call to this
1072 function.
1073 
1074  * `PACKAGE`: (Required) The package installed by this call. Currently,
1075  subpackages must have their own call to this function.
1076  * `FILES`: (Required) File paths should be relative to the source directory
1077  of the calling `CMakeLists.txt`. Upward paths are not supported (nor are
1078  checked for). Absolute paths are assumed to be in the build tree and their
1079  relative path is computed relative to the current binary directory.
1080  * `MODULE_DESTINATION`: Modules will be placed in this location in the
1081  build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
1082  currently does not. See `vtk_module_python_default_destination` for the
1083  default value.
1084  * `COMPONENT`: Defaults to `python`. All install rules created by this
1085  function will use this installation component.
1086 
1087 A `<module>-<package>` target is created which ensures that all Python modules
1088 have been copied to the correct location in the build tree.
1089 
1090 @todo Support freezing the Python package. This should create a header and the
1091 associated target should provide an interface for including this header. The
1092 target should then be exported and the header installed properly.
1093 #]==]
1094 function (vtk_module_add_python_package name)
1095  if (NOT name STREQUAL _vtk_build_module)
1096  message(FATAL_ERROR
1097  "Python modules must match their module names.")
1098  endif ()
1099 
1100  cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_package
1101  ""
1102  "PACKAGE;MODULE_DESTINATION;COMPONENT"
1103  "FILES")
1104 
1105  if (_vtk_add_python_package_UNPARSED_ARGUMENTS)
1106  message(FATAL_ERROR
1107  "Unparsed arguments for vtk_module_add_python_package: "
1108  "${_vtk_add_python_package_UNPARSED_ARGUMENTS}")
1109  endif ()
1110 
1111  if (NOT _vtk_add_python_package_PACKAGE)
1112  message(FATAL_ERROR
1113  "The `PACKAGE` argument is required.")
1114  endif ()
1115  string(REPLACE "." "/" _vtk_add_python_package_path "${_vtk_add_python_package_PACKAGE}")
1116 
1117  if (NOT _vtk_add_python_package_FILES)
1118  message(FATAL_ERROR
1119  "The `FILES` argument is required.")
1120  endif ()
1121 
1122  if (NOT DEFINED _vtk_add_python_package_MODULE_DESTINATION)
1123  vtk_module_python_default_destination(_vtk_add_python_package_MODULE_DESTINATION)
1124  endif ()
1125 
1126  if (NOT DEFINED _vtk_add_python_package_COMPONENT)
1127  set(_vtk_add_python_package_COMPONENT "python")
1128  endif ()
1129 
1130  set(_vtk_add_python_package_file_outputs)
1131  foreach (_vtk_add_python_package_file IN LISTS _vtk_add_python_package_FILES)
1132  if (IS_ABSOLUTE "${_vtk_add_python_package_file}")
1133  file(RELATIVE_PATH _vtk_add_python_package_name
1134  "${CMAKE_CURRENT_BINARY_DIR}"
1135  "${_vtk_add_python_package_file}")
1136  else ()
1137  set(_vtk_add_python_package_name
1138  "${_vtk_add_python_package_file}")
1139  string(PREPEND _vtk_add_python_package_file
1140  "${CMAKE_CURRENT_SOURCE_DIR}/")
1141  endif ()
1142 
1143  set(_vtk_add_python_package_file_output
1144  "${CMAKE_BINARY_DIR}/${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_name}")
1145  add_custom_command(
1146  OUTPUT "${_vtk_add_python_package_file_output}"
1147  DEPENDS "${_vtk_add_python_package_file}"
1148  COMMAND "${CMAKE_COMMAND}" -E copy_if_different
1149  "${_vtk_add_python_package_file}"
1150  "${_vtk_add_python_package_file_output}"
1151  COMMENT "Copying ${_vtk_add_python_package_name} to the binary directory")
1152  list(APPEND _vtk_add_python_package_file_outputs
1153  "${_vtk_add_python_package_file_output}")
1154  if (BUILD_SHARED_LIBS)
1155  get_filename_component(_vtk_add_python_package_install_path "${_vtk_add_python_package_name}" DIRECTORY)
1156  install(
1157  FILES "${_vtk_add_python_package_name}"
1158  DESTINATION "${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_install_path}"
1159  COMPONENT "${_vtk_add_python_package_COMPONENT}")
1160  endif()
1161  endforeach ()
1162 
1163  get_property(_vtk_add_python_package_module GLOBAL
1164  PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
1165  add_custom_target("${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}" ALL
1166  DEPENDS
1167  ${_vtk_add_python_package_file_outputs})
1168 
1169  # Set `python_modules` to provide the list of python files that go along with
1170  # this module
1171  set_property(TARGET "${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}"
1172  PROPERTY
1173  "python_modules" "${_vtk_add_python_package_file_outputs}")
1174 endfunction ()
1175 
1176 #[==[
1177 @ingroup module-wrapping-python
1178 @brief Use a Python package as a module
1179 
1180 If a module is a Python package, this function should be used instead of
1181 @ref vtk_module_add_module.
1182 
1183 ~~~
1184 vtk_module_add_python_module(<name>
1185  PACKAGES <packages>...)
1186 ~~~
1187 
1188  * `PACKAGES`: (Required) The list of packages installed by this module.
1189  These must have been created by the @ref vtk_module_add_python_package
1190  function.
1191 #]==]
1192 function (vtk_module_add_python_module name)
1193  if (NOT name STREQUAL _vtk_build_module)
1194  message(FATAL_ERROR
1195  "Python modules must match their module names.")
1196  endif ()
1197 
1198  cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_module
1199  ""
1200  ""
1201  "PACKAGES")
1202 
1203  if (_vtk_add_python_module_UNPARSED_ARGUMENTS)
1204  message(FATAL_ERROR
1205  "Unparsed arguments for vtk_module_add_python_module: "
1206  "${_vtk_add_python_module_UNPARSED_ARGUMENTS}")
1207  endif ()
1208 
1209  get_property(_vtk_add_python_module_depends GLOBAL
1210  PROPERTY "_vtk_module_${_vtk_build_module}_depends")
1211  get_property(_vtk_add_python_module_target_name GLOBAL
1212  PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
1213  add_library("${_vtk_add_python_module_target_name}" INTERFACE)
1214  target_link_libraries("${_vtk_add_python_module_target_name}"
1215  INTERFACE
1216  ${_vtk_add_python_module_depends})
1217  if (NOT _vtk_build_module STREQUAL _vtk_add_python_module_target_name)
1218  add_library("${_vtk_build_module}" ALIAS
1219  "${_vtk_add_python_module_target_name}")
1220  endif ()
1221  foreach (_vtk_add_python_module_package IN LISTS _vtk_add_python_module_PACKAGES)
1222  add_dependencies("${_vtk_add_python_module_target_name}"
1223  "${_vtk_build_module}-${_vtk_add_python_module_package}")
1224 
1225  # get the list of python files and add them on the module.
1226  get_property(_vtk_module_python_modules
1227  TARGET "${_vtk_add_python_module_target_name}-${_vtk_add_python_module_package}"
1228  PROPERTY "python_modules")
1229  _vtk_module_set_module_property("${_vtk_build_module}" APPEND
1230  PROPERTY "python_modules"
1231  VALUE "${_vtk_module_python_modules}")
1232  endforeach ()
1233 
1234  get_property(_vtk_add_python_module_LICENSE_FILES GLOBAL
1235  PROPERTY "_vtk_module_${_vtk_build_module}_license_files")
1236  if (_vtk_add_python_module_LICENSE_FILES)
1237  if (_vtk_build_TARGET_SPECIFIC_COMPONENTS)
1238  string(PREPEND _vtk_build_LICENSE_COMPONENT "${_vtk_build_module}-")
1239  endif ()
1240  install(
1241  FILES ${_vtk_add_python_module_LICENSE_FILES}
1242  DESTINATION "${_vtk_build_LICENSE_DESTINATION}/${_vtk_add_python_module_target_name}/"
1243  COMPONENT "${_vtk_build_LICENSE_COMPONENT}")
1244  endif ()
1245 
1246  _vtk_module_apply_properties("${_vtk_add_python_module_target_name}")
1247  _vtk_module_install("${_vtk_add_python_module_target_name}")
1248 endfunction ()
1249 
1250 cmake_policy(POP)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
boost::graph_traits< vtkGraph * >::vertex_descriptor target(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)