2@defgroup module-wrapping-python Module Python CMake APIs
6@file vtkModuleWrapPython.cmake
7@brief APIs
for wrapping modules
for Python
9@section python-wrapping-limitations Limitations
11Known limitations include:
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
24@ingroup module-wrapping-python
25@brief Determine Python module destination
27Some projects may need to know where Python expects its modules to be placed in
28the install tree (assuming a shared prefix). This function computes the default
29and sets the passed variable to the value in the calling scope.
32vtk_module_python_default_destination(<var>
33 [MAJOR_VERSION <major>])
36By default, the destination is `${CMAKE_INSTALL_BINDIR}/Lib/site-packages` on
37Windows and `${CMAKE_INSTALL_LIBDIR}/python<VERSION>/site-packages` otherwise.
39`<MAJOR_VERSION>` must be one of `2` or `3`. If not specified, it defaults to
40the value of `${VTK_PYTHON_VERSION}`.
44cmake_policy(SET CMP0053 NEW)
46function (vtk_module_python_default_destination var)
47 cmake_parse_arguments(PARSE_ARGV 1 _vtk_module_python
52 if (_vtk_module_python_UNPARSED_ARGUMENTS)
54 "Unparsed arguments for vtk_module_python_default_destination: "
55 "${_vtk_module_python_UNPARSED_ARGUMENTS}")
58 if (NOT _vtk_module_python_MAJOR_VERSION)
59 if (NOT DEFINED VTK_PYTHON_VERSION)
61 "A major version of Python must be specified (or `VTK_PYTHON_VERSION` "
65 set(_vtk_module_python_MAJOR_VERSION "${VTK_PYTHON_VERSION}")
68 if (NOT _vtk_module_python_MAJOR_VERSION STREQUAL "2" AND
69 NOT _vtk_module_python_MAJOR_VERSION STREQUAL "3")
71 "Only Python2 and Python3 are supported right now.")
74 if (WIN32 AND NOT CYGWIN)
75 set(destination "${CMAKE_INSTALL_BINDIR}/Lib/site-packages")
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)
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}")
86 "The version of Python is unknown; not using a versioned directory "
87 "for Python modules.")
88 set(_vtk_python_version_suffix)
90 set(destination "${CMAKE_INSTALL_LIBDIR}/python${_vtk_python_version_suffix}/site-packages")
93 set("${var}" "${destination}" PARENT_SCOPE)
98@brief Generate sources for using a module's classes from Python
100This function generates the wrapped sources
for a module. It places the list of
101generated
source files and classes in variables named in the second and third
102arguments, respectively.
105_vtk_module_wrap_python_sources(<module> <sources> <classes>)
110 PROPERTY
"exclude_wrap"
111 VARIABLE _vtk_python_exclude_wrap)
112 if (_vtk_python_exclude_wrap)
116 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python
")
118 set(_vtk_python_args_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python/${_vtk_python_library_name}-python.$<CONFIGURATION>.args
")
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}
")
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}
"
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}
"
146 if (_vtk_python_is_imported OR CMAKE_GENERATOR MATCHES "Ninja
")
147 list(APPEND _vtk_python_command_depends "${_vtk_python_hierarchy_file}
")
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
")
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
"
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>
")
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")
174 set(_vtk_python_sources)
176 # Get the list of public headers from the module.
177 _vtk_module_get_module_property("${module}"
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
184 get_filename_component(_vtk_python_basename "${_vtk_python_header}" NAME_WE)
185 list(APPEND _vtk_python_classes
186 "${_vtk_python_basename}")
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}")
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
202 -imacros "${_VTKCompileTools_macros_file}")
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}
215 CXX "${_vtk_python_header}"
216 COMMENT "Generating Python wrapper sources for ${_vtk_python_basename}"
218 "${_vtk_python_header}"
219 "${_vtk_python_args_file}"
220 "$<TARGET_FILE:${_vtk_python_wrap_target}>"
221 ${_vtk_python_command_depends})
225 "${_vtk_python_sources}"
228 "${_vtk_python_classes}"
234@brief Generate a CPython library for a set of modules
236A Python module library may consist of the Python wrappings of multiple
237modules. This is useful for kit-based builds where the modules part of the same
238kit belong to the same Python module as well.
241_vtk_module_wrap_python_library(<name> <module>...)
244The first argument is the name of the Python module. The remaining arguments
245are modules to include in the Python module.
247The remaining information it uses is assumed to be provided by the
248@ref vtk_module_wrap_python function.
250function (_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)
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)
265 # Wrap the module independently of the other VTK modules in the Python
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})
273 # Make sure the module doesn't already have an associated Python package.
275 PROPERTY
"INTERFACE_vtk_module_python_package"
276 VARIABLE _vtk_python_current_python_package)
277 if (DEFINED _vtk_python_current_python_package)
279 "It appears as though the ${_vtk_python_module} has already been "
280 "wrapped in Python in the ${_vtk_python_current_python_package} "
284 PROPERTY "INTERFACE_vtk_module_python_package
"
285 VALUE "${_vtk_python_PYTHON_PACKAGE}
")
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}
"
293 # Export the wrapping hints file.
294 INTERFACE_vtk_module_python_package)
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)
308 _vtk_module_get_module_property("${_vtk_python_module}
"
309 PROPERTY "library_name
"
310 VARIABLE _vtk_python_library_name)
312 _vtk_module_get_module_property("${_vtk_python_module}
"
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)
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)
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}
")
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
")
344 OUTPUT "${_vtk_python_module_file}
"
345 CONTENT "${_vtk_python_module_contents}
")
347 # Set `python_modules` to provide the list of python files that go along with
349 _vtk_module_set_module_property("${_vtk_python_module}
" APPEND
350 PROPERTY "python_modules
"
351 VALUE "${_vtk_python_module_file}
")
355 if (NOT _vtk_python_library_sources)
359 set(_vtk_python_init_data_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${
name}Python/${
name}-init.data
")
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
")
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}
")
373 set(_vtk_python_wrap_target "VTK::WrapPythonInit
")
374 if (TARGET VTKCompileTools::WrapPythonInit)
375 set(_vtk_python_wrap_target "VTKCompileTools::WrapPythonInit
")
378 if(_vtk_python_BUILD_STATIC)
379 set(additonal_options "${_vtk_python_import_prefix}
")
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}
"
391 "${_vtk_python_init_data_file}
"
392 "$<TARGET_FILE:${_vtk_python_wrap_target}>
")
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
401#include <vtkPython.h>
406#if PY_VERSION_HEX < 0x03000000
407extern void init${_vtk_python_library_name}();
409extern PyObject* PyInit_${_vtk_python_library_name}();
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}"
427 add_library(
"${name}" STATIC
428 ${_vtk_python_library_sources}
429 "${_vtk_python_module_header_file}")
430 target_include_directories(
"${name}"
432 "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}/static_python>")
433 target_link_libraries(
"${name}"
437 if (_vtk_python_UTILITY_TARGET)
438 target_link_libraries(
"${name}"
440 "${_vtk_python_UTILITY_TARGET}")
443 set_property(TARGET "${
name}
"
445 LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_python_STATIC_MODULE_DESTINATION}
")
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
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}
"
464 set_property(TARGET "${
name}
"
468 set_property(TARGET "${
name}
"
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}
"
480 "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}
" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}
")
484 if (_vtk_python_UTILITY_TARGET)
485 target_link_libraries("${
name}
"
487 "${_vtk_python_UTILITY_TARGET}
")
490 set_target_properties("${
name}
"
493 OUTPUT_NAME "${_vtk_python_library_name}
"
494 ARCHIVE_OUTPUT_NAME "${
name}
")
501 # The wrapper code will expand PYTHON_PACKAGE as needed
502 target_compile_definitions("${
name}
"
504 "-DPYTHON_PACKAGE=\
"${_vtk_python_PYTHON_PACKAGE}\"")
506 target_link_libraries(
"${name}"
509 VTK::WrappingPythonCore
512 set(_vtk_python_export)
513 if (_vtk_python_INSTALL_EXPORT)
514 list(APPEND _vtk_python_export
515 EXPORT
"${_vtk_python_INSTALL_EXPORT}")
518 set(_vtk_python_wrap_component "${_vtk_python_COMPONENT}
")
519 if (_vtk_python_TARGET_SPECIFIC_COMPONENTS)
520 string(PREPEND _vtk_python_wrap_component "${
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}
")
533@ingroup module-wrapping-python
534@brief Wrap a set of modules for use in Python
537vtk_module_wrap_python(
540 [WRAPPED_MODULES <varname>]
542 [BUILD_STATIC <ON|OFF>]
543 [INSTALL_HEADERS <ON|OFF>]
545 [DEPENDS <target>...]
546 [UTILITY_TARGET <target>]
548 [MODULE_DESTINATION <destination>]
549 [STATIC_MODULE_DESTINATION <destination>]
550 [CMAKE_DESTINATION <destination>]
551 [LIBRARY_DESTINATION <destination>]
553 [PYTHON_PACKAGE <package>]
555 [USE_DEBUG_SUFFIX <ON|OFF>]
557 [INSTALL_EXPORT <export>]
558 [COMPONENT <component>])
559 [TARGET_SPECIFIC_COMPONENTS <ON|OFF>]
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
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
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
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
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.
613function (vtk_module_wrap_python)
614 cmake_parse_arguments(PARSE_ARGV 0 _vtk_python
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
"
619 if (_vtk_python_UNPARSED_ARGUMENTS)
622 "${_vtk_python_UNPARSED_ARGUMENTS}
")
625 if (NOT _vtk_python_MODULES)
627 "No modules were requested
for Python wrapping.
")
631 _vtk_module_split_module_name("${_vtk_python_TARGET}
" _vtk_python)
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}
")
640 if (NOT DEFINED _vtk_python_MODULE_DESTINATION)
641 vtk_module_python_default_destination(_vtk_python_MODULE_DESTINATION)
644 if (NOT DEFINED _vtk_python_INSTALL_HEADERS)
645 set(_vtk_python_INSTALL_HEADERS ON)
648 if (NOT DEFINED _vtk_python_TARGET_SPECIFIC_COMPONENTS)
649 set(_vtk_python_TARGET_SPECIFIC_COMPONENTS OFF)
652 if (NOT DEFINED _vtk_python_USE_DEBUG_SUFFIX)
653 set(_vtk_python_USE_DEBUG_SUFFIX OFF)
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}
")
666 string(TOUPPER "${CMAKE_BUILD_TYPE}
" _vtk_python_upper_config)
667 set("CMAKE_${_vtk_python_upper_config}_POSTFIX
"
668 ".${_vtk_python_SOABI}
")
672 if (_vtk_python_INSTALL_HEADERS AND NOT DEFINED _vtk_python_CMAKE_DESTINATION)
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
"
679 if (NOT DEFINED _vtk_python_BUILD_STATIC)
680 if (BUILD_SHARED_LIBS)
681 set(_vtk_python_BUILD_STATIC OFF)
683 set(_vtk_python_BUILD_STATIC ON)
686 if (NOT _vtk_python_BUILD_STATIC AND NOT BUILD_SHARED_LIBS)
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.
")
694 if (NOT DEFINED _vtk_python_STATIC_MODULE_DESTINATION)
695 # TODO: Is this correct?
696 set(_vtk_python_STATIC_MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}
")
699 if (NOT DEFINED _vtk_python_COMPONENT)
700 set(_vtk_python_COMPONENT "python
")
703 if (NOT _vtk_python_PYTHON_PACKAGE)
705 "No `PYTHON_PACKAGE` was given; Python modules must be placed into a
"
708 string(REPLACE ".
" "/
" _vtk_python_package_path "${_vtk_python_PYTHON_PACKAGE}
")
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
716 string(REPLACE ".
" "_
" _vtk_python_import_prefix "${_vtk_python_PYTHON_PACKAGE}_
")
718 # We are building dynamic libraries therefore the prefix is simply '.'
719 set(_vtk_python_import_prefix ".
")
722 _vtk_module_check_destinations(_vtk_python_
724 STATIC_MODULE_DESTINATION
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}
")
733 file(WRITE "${_vtk_python_properties_build_file}
")
734 file(WRITE "${_vtk_python_properties_install_file}
")
737 if (DEFINED _vtk_python_LIBRARY_DESTINATION)
739 set(CMAKE_BUILD_RPATH_USE_ORIGIN 1)
741 file(RELATIVE_PATH _vtk_python_relpath
742 "/prefix/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}
"
743 "/prefix/${_vtk_python_LIBRARY_DESTINATION}
")
746 set(_vtk_python_origin_stem "@loader_path
")
748 set(_vtk_python_origin_stem "$ORIGIN
")
751 list(APPEND CMAKE_INSTALL_RPATH
752 "${_vtk_python_origin_stem}/${_vtk_python_relpath}
")
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}
"
760 VARIABLE "_vtk_python_${_vtk_python_module}_depends
")
762 vtk_topological_sort(_vtk_python_sorted_modules "_vtk_python_
" "_depends
")
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}
")
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}-
")
779 # Disable CMake's automoc support for these targets.
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}
")
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}
")
800 if (NOT _vtk_python_all_modules)
802 "No modules given could be wrapped.
")
805 if (_vtk_python_INSTALL_HEADERS)
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}
")
813 if (DEFINED _vtk_python_WRAPPED_MODULES)
814 set("${_vtk_python_WRAPPED_MODULES}
"
815 "${_vtk_python_all_wrapped_modules}
"
819 if (_vtk_python_TARGET)
820 add_library("${_vtk_python_TARGET_NAME}
" INTERFACE)
821 target_include_directories("${_vtk_python_TARGET_NAME}
"
823 "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python>
")
824 target_link_libraries("${_vtk_python_TARGET_NAME}
"
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}
")
832 if (_vtk_python_INSTALL_EXPORT)
834 TARGETS "${_vtk_python_TARGET_NAME}
"
835 EXPORT "${_vtk_python_INSTALL_EXPORT}
"
836 COMPONENT "${_vtk_python_headers_component}
")
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
")
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")
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")
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();
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); }
868#define PY_APPEND_INIT_OR_IMPORT(module, do_import) \\
869 if (do_import) { PY_IMPORT(module); } else { PY_APPEND_INIT(module); }
871static void ${_vtk_python_TARGET_NAME}_load() {\n")
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")
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)
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
")
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
")
895 # TODO: Install this header.
897 OUTPUT "${_vtk_python_all_modules_include_file}
"
898 CONTENT "${_vtk_python_all_modules_include_content}
")
900 if (_vtk_python_BUILD_STATIC)
901 # TODO: Install these targets.
902 target_link_libraries("${_vtk_python_TARGET_NAME}
"
904 ${_vtk_python_all_modules})
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 "
915#include <vtkPython.h>
916#include \"${_vtk_python_TARGET_NAME}.h\"
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
926 Py${_vtk_python_static_importer_name}_Methods, // m_methods
934#if PY_VERSION_HEX >= 0x03000000
935 PyMODINIT_FUNC PyInit_${_vtk_python_static_importer_name}(void)
937 PyMODINIT_FUNC init${_vtk_python_static_importer_name}(void)
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);
946 Py_InitModule(\"${_vtk_python_static_importer_name}\", Py${_vtk_python_static_importer_name}_Methods);
950 # TODO: Install this header.
952 OUTPUT
"${_vtk_python_static_importer_file}"
953 CONTENT
"${_vtk_python_static_importer_content}")
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}"
962 set_property(TARGET "${_vtk_python_static_importer_name}
"
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}
"
974 "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}
" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}
")
977 set_property(TARGET "${_vtk_python_static_importer_name}
"
980 target_link_libraries("${_vtk_python_static_importer_name}
"
982 ${_vtk_python_TARGET_NAME}
983 VTK::WrappingPythonCore
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)
997@ingroup module-wrapping-python
998@brief Install Python packages with a module
1000Some modules may have associated Python code. This function should be used to
1004vtk_module_add_python_package(<module>
1007 [MODULE_DESTINATION <destination>]
1008 [COMPONENT <component>])
1011The `<module>` argument must match the associated VTK module that the package
1012is with. Each package is independent and should be installed separately. That
1013is, `package` and `package.subpackage` should each get their own call to this
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
1026 * `COMPONENT`: Defaults to `python`. All install rules created by this
1027 function will use this installation component.
1029A `<module>-<package>` target is created which ensures that all Python modules
1030have been copied to the correct location in the build tree.
1032@todo Support freezing the Python package. This should create a header and the
1033associated target should provide an interface for including this header. The
1034target should then be exported and the header installed properly.
1036function (vtk_module_add_python_package name)
1037 if (NOT name STREQUAL _vtk_build_module)
1039 "Python modules must match their module names.
")
1042 cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_package
1044 "PACKAGE;MODULE_DESTINATION;COMPONENT
"
1047 if (_vtk_add_python_package_UNPARSED_ARGUMENTS)
1050 "${_vtk_add_python_package_UNPARSED_ARGUMENTS}
")
1053 if (NOT _vtk_add_python_package_PACKAGE)
1055 "The `PACKAGE` argument is required.
")
1057 string(REPLACE ".
" "/
" _vtk_add_python_package_path "${_vtk_add_python_package_PACKAGE}
")
1059 if (NOT _vtk_add_python_package_FILES)
1061 "The `FILES` argument is required.
")
1064 if (NOT DEFINED _vtk_add_python_package_MODULE_DESTINATION)
1065 vtk_module_python_default_destination(_vtk_add_python_package_MODULE_DESTINATION)
1068 if (NOT DEFINED _vtk_add_python_package_COMPONENT)
1069 set(_vtk_add_python_package_COMPONENT "python
")
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}
")
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}/
")
1085 set(_vtk_add_python_package_file_output
1086 "${CMAKE_BINARY_DIR}/${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_name}
")
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)
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}
")
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
1109 ${_vtk_add_python_package_file_outputs})
1111 # Set `python_modules` to provide the list of python files that go along with
1113 set_property(TARGET "${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}
"
1115 "python_modules
" "${_vtk_add_python_package_file_outputs}
")
1119@ingroup module-wrapping-python
1120@brief Use a Python package as a module
1122If a module is a Python package, this function should be used instead of
1123@ref vtk_module_add_module.
1126vtk_module_add_python_module(<name>
1127 PACKAGES <packages>...)
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
1134function (vtk_module_add_python_module name)
1135 if (NOT name STREQUAL _vtk_build_module)
1137 "Python modules must match their module names.
")
1140 cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_module
1145 if (_vtk_add_python_module_UNPARSED_ARGUMENTS)
1148 "${_vtk_add_python_module_UNPARSED_ARGUMENTS}
")
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}
"
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}
")
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}
")
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}
")
1176 _vtk_module_apply_properties("${_vtk_add_python_module_target_name}
")
1177 _vtk_module_install("${_vtk_add_python_module_target_name}
")
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.
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 *)