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