VTK  9.1.0
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 (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
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 
545  [DEPENDS <target>...]
546  [UTILITY_TARGET <target>]
547 
548  [MODULE_DESTINATION <destination>]
549  [STATIC_MODULE_DESTINATION <destination>]
550  [CMAKE_DESTINATION <destination>]
551  [LIBRARY_DESTINATION <destination>]
552 
553  [PYTHON_PACKAGE <package>]
554  [SOABI <soabi>]
555  [USE_DEBUG_SUFFIX <ON|OFF>]
556 
557  [INSTALL_EXPORT <export>]
558  [COMPONENT <component>])
559  [TARGET_SPECIFIC_COMPONENTS <ON|OFF>]
560 ~~~
561 
562  * `MODULES`: (Required) The list of modules to wrap.
563  * `TARGET`: (Recommended) The target to create which represents all wrapped
564  Python modules. This is mostly useful when supporting static Python modules
565  in order to add the generated modules to the built-in table.
566  * `WRAPPED_MODULES`: (Recommended) Not all modules are wrappable. This
567  variable will be set to contain the list of modules which were wrapped.
568  These modules will have a `INTERFACE_vtk_module_python_package` property
569  set on them which is the name that should be given to `import` statements
570  in Python code.
571  * `BUILD_STATIC`: Defaults to `${BUILD_SHARED_LIBS}`. Note that shared
572  modules with a static build is not completely supported. For static Python
573  module builds, a header named `<TARGET>.h` will be available with a
574  function `void <TARGET>_load()` which will add all Python modules created
575  by this call to the imported module table. For shared Python module builds,
576  the same function is provided, but it is a no-op.
577  * `INSTALL_HEADERS` (Defaults to `ON`): If unset, CMake properties will not
578  be installed.
579  * `TARGET_SPECIFIC_COMPONENTS` (Defaults to `OFF`): If set, prepend the
580  output target name to the install component (`<TARGET>-<COMPONENT>`).
581  * `DEPENDS`: This is list of other Python modules targets i.e. targets
582  generated from previous calls to `vtk_module_wrap_python` that this new
583  target depends on. This is used when `BUILD_STATIC` is true to ensure that
584  the `void <TARGET>_load()` is correctly called for each of the dependencies.
585  * `UTILITY_TARGET`: If specified, all libraries made by the Python wrapping
586  will link privately to this target. This may be used to add compile flags
587  to the Python libraries.
588  * `MODULE_DESTINATION`: Modules will be placed in this location in the
589  build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
590  currently does not. See `vtk_module_python_default_destination` for the
591  default value.
592  * `STATIC_MODULE_DESTINATION`: Defaults to `${CMAKE_INSTALL_LIBDIR}`. This
593  default may change in the future since the best location for these files is
594  not yet known. Static libraries containing Python code will be installed to
595  the install tree under this path.
596  * `CMAKE_DESTINATION`: (Required if `INSTALL_HEADERS` is `ON`) Where to
597  install Python-related module property CMake files.
598  * `LIBRARY_DESTINATION` (Recommended): If provided, dynamic loader
599  information will be added to modules for loading dependent libraries.
600  * `PYTHON_PACKAGE`: (Recommended) All generated modules will be added to this
601  Python package. The format is in Python syntax (e.g.,
602  `package.subpackage`).
603  * `SOABI`: (Required for wheel support): If given, generate libraries with
604  the SOABI tag in the module filename.
605  * `USE_DEBUG_SUFFIX` (Defaults to `OFF`): If `ON`, Windows modules will have
606  a `_d` suffix appended to the module name. This is intended for use with
607  debug Python builds.
608  * `INSTALL_EXPORT`: If provided, static installs will add the installed
609  libraries to the provided export set.
610  * `COMPONENT`: Defaults to `python`. All install rules created by this
611  function will use this installation component.
612 #]==]
613 function (vtk_module_wrap_python)
614  cmake_parse_arguments(PARSE_ARGV 0 _vtk_python
615  ""
616  "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"
617  "DEPENDS;MODULES")
618 
619  if (_vtk_python_UNPARSED_ARGUMENTS)
620  message(FATAL_ERROR
621  "Unparsed arguments for vtk_module_wrap_python: "
622  "${_vtk_python_UNPARSED_ARGUMENTS}")
623  endif ()
624 
625  if (NOT _vtk_python_MODULES)
626  message(WARNING
627  "No modules were requested for Python wrapping.")
628  return ()
629  endif ()
630 
631  _vtk_module_split_module_name("${_vtk_python_TARGET}" _vtk_python)
632 
633  set(_vtk_python_depends)
634  foreach (_vtk_python_depend IN LISTS _vtk_python_DEPENDS)
635  _vtk_module_split_module_name("${_vtk_python_depend}" _vtk_python_depends)
636  list(APPEND _vtk_python_depends
637  "${_vtk_python_depends_TARGET_NAME}")
638  endforeach ()
639 
640  if (NOT DEFINED _vtk_python_MODULE_DESTINATION)
641  vtk_module_python_default_destination(_vtk_python_MODULE_DESTINATION)
642  endif ()
643 
644  if (NOT DEFINED _vtk_python_INSTALL_HEADERS)
645  set(_vtk_python_INSTALL_HEADERS ON)
646  endif ()
647 
648  if (NOT DEFINED _vtk_python_TARGET_SPECIFIC_COMPONENTS)
649  set(_vtk_python_TARGET_SPECIFIC_COMPONENTS OFF)
650  endif ()
651 
652  if (NOT DEFINED _vtk_python_USE_DEBUG_SUFFIX)
653  set(_vtk_python_USE_DEBUG_SUFFIX OFF)
654  endif ()
655 
656  if (_vtk_python_SOABI)
657  get_property(_vtk_python_is_multi_config GLOBAL
658  PROPERTY GENERATOR_IS_MULTI_CONFIG)
659  if (_vtk_python_is_multi_config)
660  foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
661  string(TOUPPER "${_vtk_python_config}" _vtk_python_upper_config)
662  set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
663  ".${_vtk_python_SOABI}")
664  endforeach ()
665  else ()
666  string(TOUPPER "${CMAKE_BUILD_TYPE}" _vtk_python_upper_config)
667  set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
668  ".${_vtk_python_SOABI}")
669  endif ()
670  endif ()
671 
672  if (_vtk_python_INSTALL_HEADERS AND NOT DEFINED _vtk_python_CMAKE_DESTINATION)
673  message(FATAL_ERROR
674  "No CMAKE_DESTINATION set, but headers from the Python wrapping were "
675  "requested for install and the CMake files are required to work with "
676  "them.")
677  endif ()
678 
679  if (NOT DEFINED _vtk_python_BUILD_STATIC)
680  if (BUILD_SHARED_LIBS)
681  set(_vtk_python_BUILD_STATIC OFF)
682  else ()
683  set(_vtk_python_BUILD_STATIC ON)
684  endif ()
685  else ()
686  if (NOT _vtk_python_BUILD_STATIC AND NOT BUILD_SHARED_LIBS)
687  message(WARNING
688  "Building shared Python modules against static VTK modules only "
689  "supports consuming the VTK modules via their Python interfaces due "
690  "to the lack of support for an SDK to use the same static libraries.")
691  endif ()
692  endif ()
693 
694  if (NOT DEFINED _vtk_python_STATIC_MODULE_DESTINATION)
695  # TODO: Is this correct?
696  set(_vtk_python_STATIC_MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}")
697  endif ()
698 
699  if (NOT DEFINED _vtk_python_COMPONENT)
700  set(_vtk_python_COMPONENT "python")
701  endif ()
702 
703  if (NOT _vtk_python_PYTHON_PACKAGE)
704  message(FATAL_ERROR
705  "No `PYTHON_PACKAGE` was given; Python modules must be placed into a "
706  "package.")
707  endif ()
708  string(REPLACE "." "/" _vtk_python_package_path "${_vtk_python_PYTHON_PACKAGE}")
709 
710  if(_vtk_python_BUILD_STATIC)
711  # When doing static builds we want the statically initialized built-ins to be
712  # used. It is unclear in the Python-C API how to construct `namespace.module`
713  # so instead at the C++ level we import "namespace_module" during startup
714  # and than the python modules moving those imports into the correct python
715  # module.
716  string(REPLACE "." "_" _vtk_python_import_prefix "${_vtk_python_PYTHON_PACKAGE}_")
717  else()
718  # We are building dynamic libraries therefore the prefix is simply '.'
719  set(_vtk_python_import_prefix ".")
720  endif()
721 
722  _vtk_module_check_destinations(_vtk_python_
723  MODULE_DESTINATION
724  STATIC_MODULE_DESTINATION
725  CMAKE_DESTINATION
726  LIBRARY_DESTINATION)
727 
728  if (_vtk_python_INSTALL_HEADERS)
729  set(_vtk_python_properties_filename "${_vtk_python_PYTHON_PACKAGE}-vtk-python-module-properties.cmake")
730  set(_vtk_python_properties_install_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/${_vtk_python_properties_filename}.install")
731  set(_vtk_python_properties_build_file "${CMAKE_BINARY_DIR}/${_vtk_python_CMAKE_DESTINATION}/${_vtk_python_properties_filename}")
732 
733  file(WRITE "${_vtk_python_properties_build_file}")
734  file(WRITE "${_vtk_python_properties_install_file}")
735  endif ()
736 
737  if (DEFINED _vtk_python_LIBRARY_DESTINATION)
738  # Set up rpaths
739  set(CMAKE_BUILD_RPATH_USE_ORIGIN 1)
740  if (UNIX)
741  file(RELATIVE_PATH _vtk_python_relpath
742  "/prefix/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
743  "/prefix/${_vtk_python_LIBRARY_DESTINATION}")
744 
745  if (APPLE)
746  set(_vtk_python_origin_stem "@loader_path")
747  else ()
748  set(_vtk_python_origin_stem "$ORIGIN")
749  endif()
750 
751  list(APPEND CMAKE_INSTALL_RPATH
752  "${_vtk_python_origin_stem}/${_vtk_python_relpath}")
753  endif ()
754  endif ()
755 
756  set(_vtk_python_sorted_modules ${_vtk_python_MODULES})
757  foreach (_vtk_python_module IN LISTS _vtk_python_MODULES)
758  _vtk_module_get_module_property("${_vtk_python_module}"
759  PROPERTY "depends"
760  VARIABLE "_vtk_python_${_vtk_python_module}_depends")
761  endforeach ()
762  vtk_topological_sort(_vtk_python_sorted_modules "_vtk_python_" "_depends")
763 
764  set(_vtk_python_sorted_modules_filtered)
765  foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules)
766  if (_vtk_python_module IN_LIST _vtk_python_MODULES)
767  list(APPEND _vtk_python_sorted_modules_filtered
768  "${_vtk_python_module}")
769  endif ()
770  endforeach ()
771 
772  set(_vtk_python_headers_component "development")
773  set(_vtk_python_component "${_vtk_python_COMPONENT}")
774  if (_vtk_python_TARGET_SPECIFIC_COMPONENTS)
775  string(PREPEND _vtk_python_headers_component "${_vtk_python_TARGET_NAME}-")
776  string(PREPEND _vtk_python_component "${_vtk_python_TARGET_NAME}-")
777  endif ()
778 
779  # Disable CMake's automoc support for these targets.
780  set(CMAKE_AUTOMOC 0)
781  set(CMAKE_AUTORCC 0)
782  set(CMAKE_AUTOUIC 0)
783 
784  set(_vtk_python_all_modules)
785  set(_vtk_python_all_wrapped_modules)
786  foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
787  _vtk_module_get_module_property("${_vtk_python_module}"
788  PROPERTY "library_name"
789  VARIABLE _vtk_python_library_name)
790  _vtk_module_wrap_python_library("${_vtk_python_library_name}Python" "${_vtk_python_module}")
791 
792  if (TARGET "${_vtk_python_library_name}Python")
793  list(APPEND _vtk_python_all_modules
794  "${_vtk_python_library_name}Python")
795  list(APPEND _vtk_python_all_wrapped_modules
796  "${_vtk_python_module}")
797  endif ()
798  endforeach ()
799 
800  if (NOT _vtk_python_all_modules)
801  message(FATAL_ERROR
802  "No modules given could be wrapped.")
803  endif ()
804 
805  if (_vtk_python_INSTALL_HEADERS)
806  install(
807  FILES "${_vtk_python_properties_install_file}"
808  DESTINATION "${_vtk_python_CMAKE_DESTINATION}"
809  RENAME "${_vtk_python_properties_filename}"
810  COMPONENT "${_vtk_python_headers_component}")
811  endif ()
812 
813  if (DEFINED _vtk_python_WRAPPED_MODULES)
814  set("${_vtk_python_WRAPPED_MODULES}"
815  "${_vtk_python_all_wrapped_modules}"
816  PARENT_SCOPE)
817  endif ()
818 
819  if (_vtk_python_TARGET)
820  add_library("${_vtk_python_TARGET_NAME}" INTERFACE)
821  target_include_directories("${_vtk_python_TARGET_NAME}"
822  INTERFACE
823  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python>")
824  target_link_libraries("${_vtk_python_TARGET_NAME}"
825  INTERFACE
826  ${_vtk_python_DEPENDS})
827  if (NOT _vtk_python_TARGET STREQUAL _vtk_python_TARGET_NAME)
828  add_library("${_vtk_python_TARGET}" ALIAS
829  "${_vtk_python_TARGET_NAME}")
830  endif ()
831 
832  if (_vtk_python_INSTALL_EXPORT)
833  install(
834  TARGETS "${_vtk_python_TARGET_NAME}"
835  EXPORT "${_vtk_python_INSTALL_EXPORT}"
836  COMPONENT "${_vtk_python_headers_component}")
837  endif ()
838 
839  set(_vtk_python_all_modules_include_file
840  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_TARGET_NAME}.h")
841  set(_vtk_python_all_modules_include_content
842  "#ifndef ${_vtk_python_TARGET_NAME}_h\n#define ${_vtk_python_TARGET_NAME}_h\n")
843 
844  if (_vtk_python_BUILD_STATIC)
845  foreach (_vtk_python_module IN LISTS _vtk_python_all_modules)
846  string(APPEND _vtk_python_all_modules_include_content
847  "#include \"${_vtk_python_module}.h\"\n")
848  endforeach ()
849  endif ()
850 
851  foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
852  string(APPEND _vtk_python_all_modules_include_content
853  "#include \"${_vtk_python_depend}.h\"\n")
854  endforeach ()
855 
856  string(APPEND _vtk_python_all_modules_include_content
857 "#if PY_VERSION_HEX < 0x03000000
858 #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, init ## module)
859 #define PY_IMPORT(module) init ## module();
860 #else
861 #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, PyInit_ ## module)
862 #define PY_IMPORT(module) { \\
863  PyObject* var_ ## module = PyInit_ ## module(); \\
864  PyDict_SetItemString(PyImport_GetModuleDict(), \"${_vtk_python_import_prefix}\" #module,var_ ## module); \\
865  Py_DECREF(var_ ## module); }
866 #endif
867 
868 #define PY_APPEND_INIT_OR_IMPORT(module, do_import) \\
869  if (do_import) { PY_IMPORT(module); } else { PY_APPEND_INIT(module); }
870 
871 static void ${_vtk_python_TARGET_NAME}_load() {\n")
872 
873  foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
874  string(APPEND _vtk_python_all_modules_include_content
875  " ${_vtk_python_depend}_load();\n")
876  endforeach ()
877 
878  if (_vtk_python_BUILD_STATIC)
879  string(APPEND _vtk_python_all_modules_include_content
880  " int do_import = Py_IsInitialized();\n")
881  foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
882  _vtk_module_get_module_property("${_vtk_python_module}"
883  PROPERTY "library_name"
884  VARIABLE _vtk_python_library_name)
885  if (TARGET "${_vtk_python_library_name}Python")
886  string(APPEND _vtk_python_all_modules_include_content
887  " PY_APPEND_INIT_OR_IMPORT(${_vtk_python_library_name}, do_import);\n")
888  endif ()
889  endforeach ()
890  endif ()
891 
892  string(APPEND _vtk_python_all_modules_include_content
893  "}\n#undef PY_APPEND_INIT\n#undef PY_IMPORT\n#undef PY_APPEND_INIT_OR_IMPORT\n#endif\n")
894 
895  # TODO: Install this header.
896  file(GENERATE
897  OUTPUT "${_vtk_python_all_modules_include_file}"
898  CONTENT "${_vtk_python_all_modules_include_content}")
899 
900  if (_vtk_python_BUILD_STATIC)
901  # TODO: Install these targets.
902  target_link_libraries("${_vtk_python_TARGET_NAME}"
903  INTERFACE
904  ${_vtk_python_all_modules})
905  endif ()
906 
907  if (_vtk_python_BUILD_STATIC)
908  # Next, we generate a Python module that can be imported to import any
909  # static artifacts e.g. all wrapping Python modules in static builds,
910  # (eventually, frozen modules etc.)
911  string(REPLACE "." "_" _vtk_python_static_importer_name "_${_vtk_python_PYTHON_PACKAGE}_static")
912  set(_vtk_python_static_importer_file
913  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_static_importer_name}.c")
914  set(_vtk_python_static_importer_content "// generated file, do not edit!
915 #include <vtkPython.h>
916 #include \"${_vtk_python_TARGET_NAME}.h\"
917 
918  static PyMethodDef Py${_vtk_python_static_importer_name}_Methods[] = {
919  {NULL, NULL, 0, NULL}};
920 #if PY_VERSION_HEX >= 0x03000000
921  static PyModuleDef ${_vtk_python_static_importer_name}Module = {
922  PyModuleDef_HEAD_INIT,
923  \"${_vtk_python_static_importer_name}\", // m_name
924  \"module to import static components for ${_vtk_python_TARGET_NAME}\", // m_doc
925  0, // m_size
926  Py${_vtk_python_static_importer_name}_Methods, // m_methods
927  NULL, // m_reload
928  NULL, // m_traverse
929  NULL, // m_clear
930  NULL // m_free
931  };
932 #endif
933 
934 #if PY_VERSION_HEX >= 0x03000000
935  PyMODINIT_FUNC PyInit_${_vtk_python_static_importer_name}(void)
936 #else
937  PyMODINIT_FUNC init${_vtk_python_static_importer_name}(void)
938 #endif
939  {
940  // since this gets called after `Py_Initialize`, this will import the static
941  // modules and not just update the init table.
942  ${_vtk_python_TARGET_NAME}_load();
943 #if PY_VERSION_HEX >= 0x03000000
944  return PyModule_Create(&${_vtk_python_static_importer_name}Module);
945 #else
946  Py_InitModule(\"${_vtk_python_static_importer_name}\", Py${_vtk_python_static_importer_name}_Methods);
947 #endif
948  }\n")
949 
950  # TODO: Install this header.
951  file(GENERATE
952  OUTPUT "${_vtk_python_static_importer_file}"
953  CONTENT "${_vtk_python_static_importer_content}")
954 
955  add_library("${_vtk_python_static_importer_name}" MODULE
956  ${_vtk_python_static_importer_file})
957  if (WIN32 AND NOT CYGWIN)
958  set_property(TARGET "${_vtk_python_static_importer_name}"
959  PROPERTY
960  SUFFIX ".pyd")
961  endif()
962  set_property(TARGET "${_vtk_python_static_importer_name}"
963  PROPERTY
964  LIBRARY_OUTPUT_DIRECTORY "${_vtk_python_MODULE_DESTINATION}")
965  get_property(_vtk_python_is_multi_config GLOBAL
966  PROPERTY GENERATOR_IS_MULTI_CONFIG)
967  if (_vtk_python_is_multi_config)
968  # XXX(MultiNinja): This isn't going to work in general since MultiNinja
969  # will error about overlapping output paths.
970  foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
971  string(TOUPPER "${_vtk_python_config}" _vtk_python_config_upper)
972  set_property(TARGET "${_vtk_python_static_importer_name}"
973  PROPERTY
974  "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}")
975  endforeach ()
976  endif ()
977  set_property(TARGET "${_vtk_python_static_importer_name}"
978  PROPERTY
979  PREFIX "")
980  target_link_libraries("${_vtk_python_static_importer_name}"
981  PRIVATE
982  ${_vtk_python_TARGET_NAME}
983  VTK::WrappingPythonCore
984  VTK::Python)
985 
986  install(
987  TARGETS "${_vtk_python_static_importer_name}"
988  COMPONENT "${_vtk_python_component}"
989  RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}"
990  LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}"
991  ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}")
992  endif () # if (_vtk_python_BUILD_STATIC)
993  endif ()
994 endfunction ()
995 
996 #[==[
997 @ingroup module-wrapping-python
998 @brief Install Python packages with a module
999 
1000 Some modules may have associated Python code. This function should be used to
1001 install them.
1002 
1003 ~~~
1004 vtk_module_add_python_package(<module>
1005  PACKAGE <package>
1006  FILES <files>...
1007  [MODULE_DESTINATION <destination>]
1008  [COMPONENT <component>])
1009 ~~~
1010 
1011 The `<module>` argument must match the associated VTK module that the package
1012 is with. Each package is independent and should be installed separately. That
1013 is, `package` and `package.subpackage` should each get their own call to this
1014 function.
1015 
1016  * `PACKAGE`: (Required) The package installed by this call. Currently,
1017  subpackages must have their own call to this function.
1018  * `FILES`: (Required) File paths should be relative to the source directory
1019  of the calling `CMakeLists.txt`. Upward paths are not supported (nor are
1020  checked for). Absolute paths are assumed to be in the build tree and their
1021  relative path is computed relative to the current binary directory.
1022  * `MODULE_DESTINATION`: Modules will be placed in this location in the
1023  build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
1024  currently does not. See `vtk_module_python_default_destination` for the
1025  default value.
1026  * `COMPONENT`: Defaults to `python`. All install rules created by this
1027  function will use this installation component.
1028 
1029 A `<module>-<package>` target is created which ensures that all Python modules
1030 have been copied to the correct location in the build tree.
1031 
1032 @todo Support freezing the Python package. This should create a header and the
1033 associated target should provide an interface for including this header. The
1034 target should then be exported and the header installed properly.
1035 #]==]
1036 function (vtk_module_add_python_package name)
1037  if (NOT name STREQUAL _vtk_build_module)
1038  message(FATAL_ERROR
1039  "Python modules must match their module names.")
1040  endif ()
1041 
1042  cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_package
1043  ""
1044  "PACKAGE;MODULE_DESTINATION;COMPONENT"
1045  "FILES")
1046 
1047  if (_vtk_add_python_package_UNPARSED_ARGUMENTS)
1048  message(FATAL_ERROR
1049  "Unparsed arguments for vtk_module_add_python_package: "
1050  "${_vtk_add_python_package_UNPARSED_ARGUMENTS}")
1051  endif ()
1052 
1053  if (NOT _vtk_add_python_package_PACKAGE)
1054  message(FATAL_ERROR
1055  "The `PACKAGE` argument is required.")
1056  endif ()
1057  string(REPLACE "." "/" _vtk_add_python_package_path "${_vtk_add_python_package_PACKAGE}")
1058 
1059  if (NOT _vtk_add_python_package_FILES)
1060  message(FATAL_ERROR
1061  "The `FILES` argument is required.")
1062  endif ()
1063 
1064  if (NOT DEFINED _vtk_add_python_package_MODULE_DESTINATION)
1065  vtk_module_python_default_destination(_vtk_add_python_package_MODULE_DESTINATION)
1066  endif ()
1067 
1068  if (NOT DEFINED _vtk_add_python_package_COMPONENT)
1069  set(_vtk_add_python_package_COMPONENT "python")
1070  endif ()
1071 
1072  set(_vtk_add_python_package_file_outputs)
1073  foreach (_vtk_add_python_package_file IN LISTS _vtk_add_python_package_FILES)
1074  if (IS_ABSOLUTE "${_vtk_add_python_package_file}")
1075  file(RELATIVE_PATH _vtk_add_python_package_name
1076  "${CMAKE_CURRENT_BINARY_DIR}"
1077  "${_vtk_add_python_package_file}")
1078  else ()
1079  set(_vtk_add_python_package_name
1080  "${_vtk_add_python_package_file}")
1081  string(PREPEND _vtk_add_python_package_file
1082  "${CMAKE_CURRENT_SOURCE_DIR}/")
1083  endif ()
1084 
1085  set(_vtk_add_python_package_file_output
1086  "${CMAKE_BINARY_DIR}/${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_name}")
1087  add_custom_command(
1088  OUTPUT "${_vtk_add_python_package_file_output}"
1089  DEPENDS "${_vtk_add_python_package_file}"
1090  COMMAND "${CMAKE_COMMAND}" -E copy_if_different
1091  "${_vtk_add_python_package_file}"
1092  "${_vtk_add_python_package_file_output}"
1093  COMMENT "Copying ${_vtk_add_python_package_name} to the binary directory")
1094  list(APPEND _vtk_add_python_package_file_outputs
1095  "${_vtk_add_python_package_file_output}")
1096  if (BUILD_SHARED_LIBS)
1097  get_filename_component(_vtk_add_python_package_install_path "${_vtk_add_python_package_name}" DIRECTORY)
1098  install(
1099  FILES "${_vtk_add_python_package_name}"
1100  DESTINATION "${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_install_path}"
1101  COMPONENT "${_vtk_add_python_package_COMPONENT}")
1102  endif()
1103  endforeach ()
1104 
1105  get_property(_vtk_add_python_package_module GLOBAL
1106  PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
1107  add_custom_target("${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}" ALL
1108  DEPENDS
1109  ${_vtk_add_python_package_file_outputs})
1110 
1111  # Set `python_modules` to provide the list of python files that go along with
1112  # this module
1113  set_property(TARGET "${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}"
1114  PROPERTY
1115  "python_modules" "${_vtk_add_python_package_file_outputs}")
1116 endfunction ()
1117 
1118 #[==[
1119 @ingroup module-wrapping-python
1120 @brief Use a Python package as a module
1121 
1122 If a module is a Python package, this function should be used instead of
1123 @ref vtk_module_add_module.
1124 
1125 ~~~
1126 vtk_module_add_python_module(<name>
1127  PACKAGES <packages>...)
1128 ~~~
1129 
1130  * `PACKAGES`: (Required) The list of packages installed by this module.
1131  These must have been created by the @ref vtk_module_add_python_package
1132  function.
1133 #]==]
1134 function (vtk_module_add_python_module name)
1135  if (NOT name STREQUAL _vtk_build_module)
1136  message(FATAL_ERROR
1137  "Python modules must match their module names.")
1138  endif ()
1139 
1140  cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_module
1141  ""
1142  ""
1143  "PACKAGES")
1144 
1145  if (_vtk_add_python_module_UNPARSED_ARGUMENTS)
1146  message(FATAL_ERROR
1147  "Unparsed arguments for vtk_module_add_python_module: "
1148  "${_vtk_add_python_module_UNPARSED_ARGUMENTS}")
1149  endif ()
1150 
1151  get_property(_vtk_add_python_module_depends GLOBAL
1152  PROPERTY "_vtk_module_${_vtk_build_module}_depends")
1153  get_property(_vtk_add_python_module_target_name GLOBAL
1154  PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
1155  add_library("${_vtk_add_python_module_target_name}" INTERFACE)
1156  target_link_libraries("${_vtk_add_python_module_target_name}"
1157  INTERFACE
1158  ${_vtk_add_python_module_depends})
1159  if (NOT _vtk_build_module STREQUAL _vtk_add_python_module_target_name)
1160  add_library("${_vtk_build_module}" ALIAS
1161  "${_vtk_add_python_module_target_name}")
1162  endif ()
1163  foreach (_vtk_add_python_module_package IN LISTS _vtk_add_python_module_PACKAGES)
1164  add_dependencies("${_vtk_add_python_module_target_name}"
1165  "${_vtk_build_module}-${_vtk_add_python_module_package}")
1166 
1167  # get the list of python files and add them on the module.
1168  get_property(_vtk_module_python_modules
1169  TARGET "${_vtk_add_python_module_target_name}-${_vtk_add_python_module_package}"
1170  PROPERTY "python_modules")
1171  _vtk_module_set_module_property("${_vtk_build_module}" APPEND
1172  PROPERTY "python_modules"
1173  VALUE "${_vtk_module_python_modules}")
1174  endforeach ()
1175 
1176  _vtk_module_apply_properties("${_vtk_add_python_module_target_name}")
1177  _vtk_module_install("${_vtk_add_python_module_target_name}")
1178 endfunction ()
1179 
1180 cmake_policy(POP)
function _vtk_module_wrap_python_sources(module, sources, classes)
Generate sources for using a module's classes from Python.
function _vtk_module_get_module_property(module)
Get a module property.
function vtk_module_wrap_python()
Wrap a set of modules for use in Python.
function vtk_module_add_python_package(name)
Install Python packages with a module.
function vtk_module_add_python_module(name)
Use a Python package as a module.
function vtk_module_get_property(module)
Get a property from a module.
function vtk_module_set_property(module)
Set a property on a module.
@ EXPORT
Definition: vtkX3D.h:95
@ name
Definition: vtkX3D.h:225
@ string
Definition: vtkX3D.h:496
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
boost::graph_traits< vtkGraph * >::vertex_descriptor target(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)