2 @defgroup module-wrapping-python Module Python CMake APIs
6 @file vtkModuleWrapPython.cmake
7 @brief APIs
for wrapping modules
for Python
11 Known 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
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.
32 vtk_module_python_default_destination(<var>
33 [MAJOR_VERSION <major>])
36 By default, the destination is `${CMAKE_INSTALL_BINDIR}/Lib/site-packages` on
37 Windows 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
40 the value of `${VTK_PYTHON_VERSION}`.
42 function (vtk_module_python_default_destination var)
43 cmake_parse_arguments(_vtk_module_python
49 if (_vtk_module_python_UNPARSED_ARGUMENTS)
51 "Unparsed arguments for vtk_module_python_default_destination: "
52 "${_vtk_module_python_UNPARSED_ARGUMENTS}")
55 if (NOT _vtk_module_python_MAJOR_VERSION)
56 if (NOT DEFINED VTK_PYTHON_VERSION)
58 "A major version of Python must be specified (or `VTK_PYTHON_VERSION` "
62 set(_vtk_module_python_MAJOR_VERSION "${VTK_PYTHON_VERSION}")
65 if (NOT _vtk_module_python_MAJOR_VERSION STREQUAL "2" AND
66 NOT _vtk_module_python_MAJOR_VERSION STREQUAL "3")
68 "Only Python2 and Python3 are supported right now.")
71 if (WIN32 AND NOT CYGWIN)
72 set(destination "${CMAKE_INSTALL_BINDIR}/Lib/site-packages")
74 if (NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR" OR
75 NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR")
76 find_package("Python${_vtk_module_python_MAJOR_VERSION}" QUIET COMPONENTS Development.Module)
79 if (Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR AND Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR)
80 set(_vtk_python_version_suffix "${Python${VTK_PYTHON_VERSION}_VERSION_MAJOR}.${Python${VTK_PYTHON_VERSION}_VERSION_MINOR}")
83 "The version of Python is unknown; not using a versioned directory "
84 "for Python modules.")
85 set(_vtk_python_version_suffix)
87 set(destination "${CMAKE_INSTALL_LIBDIR}/python${_vtk_python_version_suffix}/site-packages")
90 set("${var}" "${destination}" PARENT_SCOPE)
95 @brief Generate sources for using a module's classes from Python
97 This
function generates the wrapped sources
for a module. It places the list of
98 generated
source files and classes in variables named in the second and third
99 arguments, respectively.
107 PROPERTY
"exclude_wrap"
108 VARIABLE _vtk_python_exclude_wrap)
109 if (_vtk_python_exclude_wrap)
113 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python
")
115 set(_vtk_python_args_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python/${_vtk_python_library_name}-python.$<CONFIGURATION>.args
")
117 set(_vtk_python_hierarchy_depends "${module}
")
118 _vtk_module_get_module_property("${module}
"
119 PROPERTY "private_depends
"
120 VARIABLE _vtk_python_private_depends)
121 list(APPEND _vtk_python_hierarchy_depends ${_vtk_python_private_depends})
123 set(_vtk_python_command_depends)
124 foreach (_vtk_python_hierarchy_depend IN LISTS _vtk_python_hierarchy_depends)
125 _vtk_module_get_module_property("${_vtk_python_hierarchy_depend}
"
127 VARIABLE _vtk_python_hierarchy_file)
128 if (_vtk_python_hierarchy_file)
129 list(APPEND _vtk_python_hierarchy_files "${_vtk_python_hierarchy_file}
")
130 get_property(_vtk_python_is_imported
131 TARGET "${_vtk_python_hierarchy_depend}
"
133 if (_vtk_python_is_imported OR CMAKE_GENERATOR MATCHES "Ninja
")
134 list(APPEND _vtk_python_command_depends "${_vtk_python_hierarchy_file}
")
136 _vtk_module_get_module_property("${_vtk_python_hierarchy_depend}
"
137 PROPERTY "library_name
"
138 VARIABLE _vtk_python_hierarchy_library_name)
139 if (TARGET "${_vtk_python_hierarchy_library_name}-hierarchy
")
140 list(APPEND _vtk_python_command_depends "${_vtk_python_hierarchy_library_name}-hierarchy
")
143 "The ${_vtk_python_hierarchy_depend} hierarchy file is attached to a non-imported
target "
144 "and a hierarchy
target (${_vtk_python_hierarchy_library_name}-hierarchy) is
"
151 set(_vtk_python_genex_compile_definitions
152 "$<TARGET_PROPERTY:${_vtk_python_target_name},COMPILE_DEFINITIONS>
")
153 set(_vtk_python_genex_include_directories
154 "$<TARGET_PROPERTY:${_vtk_python_target_name},INCLUDE_DIRECTORIES>
")
156 OUTPUT "${_vtk_python_args_file}
"
157 CONTENT "$<$<BOOL:${_vtk_python_genex_compile_definitions}>:\n-D\
'$<JOIN:${_vtk_python_genex_compile_definitions},\'\n-D\'>\'>\n
158 $<$<BOOL:${_vtk_python_genex_include_directories}>:\n-I\'$<JOIN:${_vtk_python_genex_include_directories},\'\n-I\'>\'>\n
159 $<$<BOOL:${_vtk_python_hierarchy_files}>:\n--types \'$<JOIN:${_vtk_python_hierarchy_files},\'\n--types \'>\'>\n")
161 set(_vtk_python_sources)
163 # Get the list of public headers from the module.
164 _vtk_module_get_module_property("${module}"
166 VARIABLE _vtk_python_headers)
167 set(_vtk_python_classes)
168 foreach (_vtk_python_header IN LISTS _vtk_python_headers)
169 # Assume the class name matches the basename of the header. This is VTK
171 get_filename_component(_vtk_python_basename "${_vtk_python_header}" NAME_WE)
172 list(APPEND _vtk_python_classes
173 "${_vtk_python_basename}")
175 set(_vtk_python_source_output
176 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python/${_vtk_python_basename}Python.cxx")
177 list(APPEND _vtk_python_sources
178 "${_vtk_python_source_output}")
180 set(_vtk_python_wrap_target "VTK::WrapPython")
181 set(_vtk_python_macros_args)
182 if (TARGET VTKCompileTools::WrapPython)
183 set(_vtk_python_wrap_target "VTKCompileTools::WrapPython")
184 if (TARGET VTKCompileTools_macros)
185 list(APPEND _vtk_python_command_depends
186 "VTKCompileTools_macros")
187 list(APPEND _vtk_python_macros_args
189 -imacros "${_VTKCompileTools_macros_file}")
194 OUTPUT "${_vtk_python_source_output}"
195 COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR}
196 "$<TARGET_FILE:${_vtk_python_wrap_target}>"
197 "@${_vtk_python_args_file}"
198 -o "${_vtk_python_source_output}"
199 "${_vtk_python_header}"
200 ${_vtk_python_macros_args}
202 CXX "${_vtk_python_header}"
203 COMMENT "Generating Python wrapper sources for ${_vtk_python_basename}"
205 "${_vtk_python_header}"
206 "${_vtk_python_args_file}"
207 "$<TARGET_FILE:${_vtk_python_wrap_target}>"
208 ${_vtk_python_command_depends})
212 "${_vtk_python_sources}"
215 "${_vtk_python_classes}"
221 @brief Generate a CPython library for a set of modules
223 A Python module library may consist of the Python wrappings of multiple
224 modules. This is useful for kit-based builds where the modules part of the same
225 kit belong to the same Python module as well.
228 _vtk_module_wrap_python_library(<name> <module>...)
231 The first argument is the name of the Python module. The remaining arguments
232 are modules to include in the Python module.
234 The remaining information it uses is assumed to be provided by the
235 @ref vtk_module_wrap_python function.
237 function (_vtk_module_wrap_python_library name)
238 set(_vtk_python_library_sources)
239 set(_vtk_python_library_classes)
240 foreach (_vtk_python_module IN LISTS ARGN)
241 _vtk_module_get_module_property("${_vtk_python_module}"
242 PROPERTY "exclude_wrap"
243 VARIABLE _vtk_python_exclude_wrap)
244 if (_vtk_python_exclude_wrap)
247 _vtk_module_real_target(_vtk_python_target_name "${_vtk_python_module}")
248 _vtk_module_get_module_property("${_vtk_python_module}"
249 PROPERTY "library_name"
250 VARIABLE _vtk_python_library_name)
252 # Wrap the module independently of the other VTK modules in the Python
254 _vtk_module_wrap_python_sources("${_vtk_python_module}" _vtk_python_sources _vtk_python_classes)
255 list(APPEND _vtk_python_library_sources
256 ${_vtk_python_sources})
257 list(APPEND _vtk_python_library_classes
258 ${_vtk_python_classes})
260 # Make sure the module doesn't already have an associated Python package.
262 PROPERTY
"INTERFACE_vtk_module_python_package"
263 VARIABLE _vtk_python_current_python_package)
264 if (DEFINED _vtk_python_current_python_package)
266 "It appears as though the ${_vtk_python_module} has already been "
267 "wrapped in Python in the ${_vtk_python_current_python_package} "
271 PROPERTY "INTERFACE_vtk_module_python_package
"
272 VALUE "${_vtk_python_PYTHON_PACKAGE}
")
274 if (_vtk_python_INSTALL_HEADERS)
275 _vtk_module_export_properties(
276 BUILD_FILE "${_vtk_python_properties_build_file}
"
277 INSTALL_FILE "${_vtk_python_properties_install_file}
"
278 MODULE "${_vtk_python_module}
"
280 # Export the wrapping hints file.
281 INTERFACE_vtk_module_python_package)
285 # The foreach needs to be split so that dependencies are guaranteed to have
286 # the INTERFACE_vtk_module_python_package property set.
287 foreach (_vtk_python_module IN LISTS ARGN)
288 _vtk_module_get_module_property("${_vtk_python_module}
"
289 PROPERTY "exclude_wrap
"
290 VARIABLE _vtk_python_exclude_wrap)
291 if (_vtk_python_exclude_wrap)
295 _vtk_module_get_module_property("${_vtk_python_module}
"
296 PROPERTY "library_name
"
297 VARIABLE _vtk_python_library_name)
299 _vtk_module_get_module_property("${_vtk_python_module}
"
301 VARIABLE _vtk_python_module_depends)
302 set(_vtk_python_module_load_depends)
303 foreach (_vtk_python_module_depend IN LISTS _vtk_python_module_depends)
304 _vtk_module_get_module_property("${_vtk_python_module_depend}
"
305 PROPERTY "exclude_wrap
"
306 VARIABLE _vtk_python_module_depend_exclude_wrap)
307 if (_vtk_python_module_depend_exclude_wrap)
311 _vtk_module_get_module_property("${_vtk_python_module_depend}
"
312 PROPERTY "python_package
"
313 VARIABLE _vtk_python_depend_module_package)
314 _vtk_module_get_module_property("${_vtk_python_module_depend}
"
315 PROPERTY "library_name
"
316 VARIABLE _vtk_python_depend_library_name)
318 # XXX(kits): This doesn't work for kits.
319 list(APPEND _vtk_python_module_load_depends
320 "${_vtk_python_depend_module_package}.${_vtk_python_depend_library_name}
")
323 if (_vtk_python_BUILD_STATIC)
324 # If static, we use .py modules that grab the contents from the baked-in modules.
325 set(_vtk_python_module_file
326 "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}/${_vtk_python_library_name}.py
")
327 set(_vtk_python_module_contents
328 "from ${_vtk_python_import_prefix}${_vtk_python_library_name}
import *\n
")
331 OUTPUT "${_vtk_python_module_file}
"
332 CONTENT "${_vtk_python_module_contents}
")
334 # Set `python_modules` to provide the list of python files that go along with
336 _vtk_module_set_module_property("${_vtk_python_module}
" APPEND
337 PROPERTY "python_modules
"
338 VALUE "${_vtk_python_module_file}
")
342 if (NOT _vtk_python_library_sources)
346 set(_vtk_python_init_data_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${
name}Python/${
name}-init.data
")
349 OUTPUT "${_vtk_python_init_data_file}
"
350 CONTENT "${_vtk_python_library_name}\n$<JOIN:${_vtk_python_classes},\n>\nDEPENDS\n$<JOIN:${_vtk_python_module_load_depends},\n>\n
")
352 set(_vtk_python_init_output
353 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${
name}Python/${
name}Init.cxx
")
354 set(_vtk_python_init_impl_output
355 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${
name}Python/${
name}InitImpl.cxx
")
356 list(APPEND _vtk_python_library_sources
357 "${_vtk_python_init_output}
"
358 "${_vtk_python_init_impl_output}
")
360 set(_vtk_python_wrap_target "VTK::WrapPythonInit
")
361 if (TARGET VTKCompileTools::WrapPythonInit)
362 set(_vtk_python_wrap_target "VTKCompileTools::WrapPythonInit
")
365 if(_vtk_python_BUILD_STATIC)
366 set(additonal_options "${_vtk_python_import_prefix}
")
369 OUTPUT "${_vtk_python_init_output}
"
370 "${_vtk_python_init_impl_output}
"
371 COMMAND "${_vtk_python_wrap_target}
"
372 "${_vtk_python_init_data_file}
"
373 "${_vtk_python_init_output}
"
374 "${_vtk_python_init_impl_output}
"
375 "${additonal_options}
"
376 COMMENT "Generating the Python module initialization sources
for ${
name}
"
378 "${_vtk_python_init_data_file}
"
379 "$<TARGET_FILE:${_vtk_python_wrap_target}>
")
381 if (_vtk_python_BUILD_STATIC)
382 set(_vtk_python_module_header_file
383 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${
name}/static_python/${
name}.h
")
384 set(_vtk_python_module_header_content
388 #include <vtkPython.h>
393 #if PY_VERSION_HEX < 0x03000000
394 extern void init${_vtk_python_library_name}();
396 extern PyObject* PyInit_${_vtk_python_library_name}();
406 OUTPUT
"${_vtk_python_module_header_file}"
407 CONTENT
"${_vtk_python_module_header_content}")
408 # XXX(cmake): Why is this necessary? One would expect that `file(GENERATE)`
409 # would do this automatically.
410 set_property(SOURCE
"${_vtk_python_module_header_file}"
414 add_library(
"${name}" STATIC
415 ${_vtk_python_library_sources}
416 "${_vtk_python_module_header_file}")
417 target_include_directories(
"${name}"
419 "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}/static_python>")
420 target_link_libraries(
"${name}"
423 set_property(TARGET
"${name}"
425 LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/${_vtk_python_STATIC_MODULE_DESTINATION}")
427 add_library(
"${name}" MODULE
428 ${_vtk_python_library_sources})
429 if (WIN32 AND NOT CYGWIN)
430 # XXX(python-debug): This is disabled out because there's no reliable way
431 # to tell whether we're using a debug build of Python or not. Since using
432 # a debug Python build is so rare, just assume we're always using a
433 # non-debug build of Python itself.
435 # The proper fix is to dig around and ask the backing `PythonN::Python`
436 # target used by `VTK::Python` for its properties to find out, per
437 # configuration, whether it is a debug build. If it is, add the postfix
438 # (regardless of VTK's build type). Otherwise, no postfix.
440 set_property(TARGET
"${name}"
445 set_property(TARGET "${
name}
"
449 set_property(TARGET "${
name}
"
451 LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}
")
452 get_property(_vtk_python_is_multi_config GLOBAL
453 PROPERTY GENERATOR_IS_MULTI_CONFIG)
454 if (_vtk_python_is_multi_config)
455 # XXX(MultiNinja): This isn't going to work in general since MultiNinja
456 # will error about overlapping output paths.
457 foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
458 string(TOUPPER "${_vtk_python_config}
" _vtk_python_config_upper)
459 set_property(TARGET "${
name}
"
461 "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}
" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}
")
464 set_target_properties("${
name}
"
467 OUTPUT_NAME "${_vtk_python_library_name}
"
468 ARCHIVE_OUTPUT_NAME "${
name}
")
475 # The wrapper code will expand PYTHON_PACKAGE as needed
476 target_compile_definitions("${
name}
"
478 "-DPYTHON_PACKAGE=\
"${_vtk_python_PYTHON_PACKAGE}\"")
480 target_link_libraries(
"${name}"
483 VTK::WrappingPythonCore
486 set(_vtk_python_export)
487 if (_vtk_python_INSTALL_EXPORT)
488 set(_vtk_python_export
489 EXPORT "${_vtk_python_INSTALL_EXPORT}")
494 ${_vtk_python_export}
495 COMPONENT "${_vtk_python_COMPONENT}
"
496 RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}
"
497 LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}
"
498 ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}
")
502 @ingroup module-wrapping-python
503 @brief Wrap a set of modules for use in Python
506 vtk_module_wrap_python(
509 [WRAPPED_MODULES <varname>]
511 [BUILD_STATIC <ON|OFF>]
512 [INSTALL_HEADERS <ON|OFF>]
514 [DEPENDS <target>...]
516 [MODULE_DESTINATION <destination>]
517 [STATIC_MODULE_DESTINATION <destination>]
518 [CMAKE_DESTINATION <destination>]
519 [LIBRARY_DESTINATION <destination>]
521 [PYTHON_PACKAGE <package>]
524 [INSTALL_EXPORT <export>]
525 [COMPONENT <component>])
528 * `MODULES`: (Required) The list of modules to wrap.
529 * `TARGET`: (Recommended) The target to create which represents all wrapped
530 Python modules. This is mostly useful when supporting static Python modules
531 in order to add the generated modules to the built-in table.
532 * `WRAPPED_MODULES`: (Recommended) Not all modules are wrappable. This
533 variable will be set to contain the list of modules which were wrapped.
534 These modules will have a `INTERFACE_vtk_module_python_package` property
535 set on them which is the name that should be given to `import` statements
537 * `BUILD_STATIC`: Defaults to `${BUILD_SHARED_LIBS}`. Note that shared
538 modules with a static build is not completely supported. For static Python
539 module builds, a header named `<TARGET>.h` will be available with a
540 function `void <TARGET>_load()` which will add all Python modules created
541 by this call to the imported module table. For shared Python module builds,
542 the same function is provided, but it is a no-op.
543 * `INSTALL_HEADERS` (Defaults to `ON`): If unset, CMake properties will not
545 * `DEPENDS`: This is list of other Python modules targets i.e. targets
546 generated from previous calls to `vtk_module_wrap_python` that this new
547 target depends on. This is used when `BUILD_STATIC` is true to ensure that
548 the `void <TARGET>_load()` is correctly called for each of the dependencies.
549 * `MODULE_DESTINATION`: Modules will be placed in this location in the
550 build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
551 currently does not. See `vtk_module_python_default_destination` for the
553 * `STATIC_MODULE_DESTINATION`: Defaults to `${CMAKE_INSTALL_LIBDIR}`. This
554 default may change in the future since the best location for these files is
555 not yet known. Static libraries containing Python code will be installed to
556 the install tree under this path.
557 * `CMAKE_DESTINATION`: (Required if `INSTALL_HEADERS` is `ON`) Where to
558 install Python-related module property CMake files.
559 * `LIBRARY_DESTINATION` (Recommended): If provided, dynamic loader
560 information will be added to modules for loading dependent libraries.
561 * `PYTHON_PACKAGE`: (Recommended) All generated modules will be added to this
562 Python package. The format is in Python syntax (e.g.,
563 `package.subpackage`).
564 * `SOABI`: (Required for wheel support): If given, generate libraries with
565 the SOABI tag in the module filename.
566 * `INSTALL_EXPORT`: If provided, static installs will add the installed
567 libraries to the provided export set.
568 * `COMPONENT`: Defaults to `python`. All install rules created by this
569 function will use this installation component.
571 function (vtk_module_wrap_python)
572 cmake_parse_arguments(_vtk_python
574 "MODULE_DESTINATION;STATIC_MODULE_DESTINATION;LIBRARY_DESTINATION;PYTHON_PACKAGE;BUILD_STATIC;INSTALL_HEADERS;INSTALL_EXPORT;TARGET;COMPONENT;WRAPPED_MODULES;CMAKE_DESTINATION;DEPENDS;SOABI
"
578 if (_vtk_python_UNPARSED_ARGUMENTS)
581 "${_vtk_python_UNPARSED_ARGUMENTS}
")
584 if (NOT _vtk_python_MODULES)
586 "No modules were requested
for Python wrapping.
")
590 _vtk_module_split_module_name("${_vtk_python_TARGET}
" _vtk_python)
592 set(_vtk_python_depends)
593 foreach (_vtk_python_depend IN LISTS _vtk_python_DEPENDS)
594 _vtk_module_split_module_name("${_vtk_python_depend}
" _vtk_python_depends)
595 list(APPEND _vtk_python_depends
596 "${_vtk_python_depends_TARGET_NAME}
")
599 if (NOT DEFINED _vtk_python_MODULE_DESTINATION)
600 vtk_module_python_default_destination(_vtk_python_MODULE_DESTINATION)
603 if (NOT DEFINED _vtk_python_INSTALL_HEADERS)
604 set(_vtk_python_INSTALL_HEADERS ON)
607 if (_vtk_python_SOABI)
608 get_property(_vtk_python_is_multi_config GLOBAL
609 PROPERTY GENERATOR_IS_MULTI_CONFIG)
610 if (_vtk_python_is_multi_config)
611 foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
612 string(TOUPPER "${_vtk_python_config}
" _vtk_python_upper_config)
613 set("CMAKE_${_vtk_python_upper_config}_POSTFIX
"
614 ".${_vtk_python_SOABI}
")
617 string(TOUPPER "${CMAKE_BUILD_TYPE}
" _vtk_python_upper_config)
618 set("CMAKE_${_vtk_python_upper_config}_POSTFIX
"
619 ".${_vtk_python_SOABI}
")
623 if (_vtk_python_INSTALL_HEADERS AND NOT DEFINED _vtk_python_CMAKE_DESTINATION)
625 "No CMAKE_DESTINATION set, but headers from the Python wrapping were
"
626 "requested
for install and the CMake files are required to work with
"
630 if (NOT DEFINED _vtk_python_BUILD_STATIC)
631 if (BUILD_SHARED_LIBS)
632 set(_vtk_python_BUILD_STATIC OFF)
634 set(_vtk_python_BUILD_STATIC ON)
637 if (NOT _vtk_python_BUILD_STATIC AND NOT BUILD_SHARED_LIBS)
639 "Building shared Python modules against
static VTK modules only
"
640 "supports consuming the VTK modules via their Python interfaces due
"
641 "to the lack of support
for an SDK to use the same
static libraries.
")
645 if (NOT DEFINED _vtk_python_STATIC_MODULE_DESTINATION)
646 # TODO: Is this correct?
647 set(_vtk_python_STATIC_MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}
")
650 if (NOT DEFINED _vtk_python_COMPONENT)
651 set(_vtk_python_COMPONENT "python
")
654 if (NOT _vtk_python_PYTHON_PACKAGE)
656 "No `PYTHON_PACKAGE` was given; Python modules must be placed into a
"
659 string(REPLACE ".
" "/
" _vtk_python_package_path "${_vtk_python_PYTHON_PACKAGE}
")
661 if(_vtk_python_BUILD_STATIC)
662 # When doing static builds we want the statically initialized built-ins to be
663 # used. It is unclear in the Python-C API how to construct `namespace.module`
664 # so instead at the C++ level we import "namespace_module
" during startup
665 # and than the python modules moving those imports into the correct python
667 string(REPLACE ".
" "_
" _vtk_python_import_prefix "${_vtk_python_PYTHON_PACKAGE}_
")
669 # We are building dynamic libraries therefore the prefix is simply '.'
670 set(_vtk_python_import_prefix ".
")
673 _vtk_module_check_destinations(_vtk_python_
675 STATIC_MODULE_DESTINATION
679 if (_vtk_python_INSTALL_HEADERS)
680 set(_vtk_python_properties_filename "${_vtk_python_PYTHON_PACKAGE}-
vtk-python-module-properties.cmake
")
681 set(_vtk_python_properties_install_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/${_vtk_python_properties_filename}.install
")
682 set(_vtk_python_properties_build_file "${CMAKE_BINARY_DIR}/${_vtk_python_CMAKE_DESTINATION}/${_vtk_python_properties_filename}
")
684 file(WRITE "${_vtk_python_properties_build_file}
")
685 file(WRITE "${_vtk_python_properties_install_file}
")
688 if (DEFINED _vtk_python_LIBRARY_DESTINATION)
690 set(CMAKE_BUILD_RPATH_USE_ORIGIN 1)
692 file(RELATIVE_PATH _vtk_python_relpath
693 "/prefix/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}
"
694 "/prefix/${_vtk_python_LIBRARY_DESTINATION}
")
697 set(_vtk_python_origin_stem "@loader_path
")
699 set(_vtk_python_origin_stem "$ORIGIN
")
702 list(APPEND CMAKE_INSTALL_RPATH
703 "${_vtk_python_origin_stem}/${_vtk_python_relpath}
")
707 set(_vtk_python_sorted_modules ${_vtk_python_MODULES})
708 foreach (_vtk_python_module IN LISTS _vtk_python_MODULES)
709 _vtk_module_get_module_property("${_vtk_python_module}
"
711 VARIABLE "_vtk_python_${_vtk_python_module}_depends
")
713 vtk_topological_sort(_vtk_python_sorted_modules "_vtk_python_
" "_depends
")
715 set(_vtk_python_sorted_modules_filtered)
716 foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules)
717 if (_vtk_python_module IN_LIST _vtk_python_MODULES)
718 list(APPEND _vtk_python_sorted_modules_filtered
719 "${_vtk_python_module}
")
723 set(_vtk_python_all_modules)
724 set(_vtk_python_all_wrapped_modules)
725 foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
726 _vtk_module_get_module_property("${_vtk_python_module}
"
727 PROPERTY "library_name
"
728 VARIABLE _vtk_python_library_name)
729 _vtk_module_wrap_python_library("${_vtk_python_library_name}Python
" "${_vtk_python_module}
")
731 if (TARGET "${_vtk_python_library_name}Python
")
732 list(APPEND _vtk_python_all_modules
733 "${_vtk_python_library_name}Python
")
734 list(APPEND _vtk_python_all_wrapped_modules
735 "${_vtk_python_module}
")
739 if (NOT _vtk_python_all_modules)
741 "No modules given could be wrapped.
")
744 if (_vtk_python_INSTALL_HEADERS)
746 FILES "${_vtk_python_properties_install_file}
"
747 DESTINATION "${_vtk_python_CMAKE_DESTINATION}
"
748 RENAME "${_vtk_python_properties_filename}
"
749 COMPONENT "development
")
752 if (DEFINED _vtk_python_WRAPPED_MODULES)
753 set("${_vtk_python_WRAPPED_MODULES}
"
754 "${_vtk_python_all_wrapped_modules}
"
758 if (_vtk_python_TARGET)
759 add_library("${_vtk_python_TARGET_NAME}
" INTERFACE)
760 target_include_directories("${_vtk_python_TARGET_NAME}
"
762 "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python>
")
763 target_link_libraries("${_vtk_python_TARGET_NAME}
"
765 ${_vtk_python_DEPENDS})
766 if (NOT _vtk_python_TARGET STREQUAL _vtk_python_TARGET_NAME)
767 add_library("${_vtk_python_TARGET}
" ALIAS
768 "${_vtk_python_TARGET_NAME}
")
771 if (_vtk_python_INSTALL_EXPORT)
773 TARGETS "${_vtk_python_TARGET_NAME}
"
774 EXPORT "${_vtk_python_INSTALL_EXPORT}
"
775 COMPONENT "development
")
778 set(_vtk_python_all_modules_include_file
779 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_TARGET_NAME}.h
")
780 set(_vtk_python_all_modules_include_content
781 "#ifndef ${_vtk_python_TARGET_NAME}_h\n#define ${_vtk_python_TARGET_NAME}_h\n
")
783 if (_vtk_python_BUILD_STATIC)
784 foreach (_vtk_python_module IN LISTS _vtk_python_all_modules)
785 string(APPEND _vtk_python_all_modules_include_content
786 "#include \
"${_vtk_python_module}.h\"\n")
790 foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
791 string(APPEND _vtk_python_all_modules_include_content
792 "
#include \"${_vtk_python_depend}.h\"\n")
795 string(APPEND _vtk_python_all_modules_include_content
796 "
#if PY_VERSION_HEX < 0x03000000
797 #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, init ## module)
798 #define PY_IMPORT(module) init ## module();
800 #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, PyInit_ ## module)
801 #define PY_IMPORT(module) { \\
802 PyObject* var_ ## module = PyInit_ ## module(); \\
803 PyDict_SetItemString(PyImport_GetModuleDict(), \"${_vtk_python_import_prefix}\" #module,var_ ## module); \\
804 Py_DECREF(var_ ## module); }
807 #define PY_APPEND_INIT_OR_IMPORT(module, do_import) \\
808 if (do_import) { PY_IMPORT(module); } else { PY_APPEND_INIT(module); }
810 static void ${_vtk_python_TARGET_NAME}_load() {\n
")
812 foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
813 string(APPEND _vtk_python_all_modules_include_content
814 " ${_vtk_python_depend}_load();\n
")
817 if (_vtk_python_BUILD_STATIC)
818 string(APPEND _vtk_python_all_modules_include_content
819 " int do_import = Py_IsInitialized();\n
")
820 foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
821 _vtk_module_get_module_property("${_vtk_python_module}
"
822 PROPERTY "library_name
"
823 VARIABLE _vtk_python_library_name)
824 if (TARGET "${_vtk_python_library_name}Python
")
825 string(APPEND _vtk_python_all_modules_include_content
826 " PY_APPEND_INIT_OR_IMPORT(${_vtk_python_library_name}, do_import);\n
")
831 string(APPEND _vtk_python_all_modules_include_content
832 "}\n#undef PY_APPEND_INIT\n#undef PY_IMPORT\n#undef PY_APPEND_INIT_OR_IMPORT\n#endif\n
")
834 # TODO: Install this header.
836 OUTPUT "${_vtk_python_all_modules_include_file}
"
837 CONTENT "${_vtk_python_all_modules_include_content}
")
839 if (_vtk_python_BUILD_STATIC)
840 # TODO: Install these targets.
841 target_link_libraries("${_vtk_python_TARGET_NAME}
"
843 ${_vtk_python_all_modules})
846 if (_vtk_python_BUILD_STATIC)
847 # Next, we generate a Python module that can be imported to import any
848 # static artifacts e.g. all wrapping Python modules in static builds,
849 # (eventually, frozen modules etc.)
850 string(REPLACE ".
" "_
" _vtk_python_static_importer_name "_${_vtk_python_PYTHON_PACKAGE}_static
")
851 set(_vtk_python_static_importer_file
852 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_static_importer_name}.c
")
853 set(_vtk_python_static_importer_content "
854 #include <vtkPython.h>
855 #include \"${_vtk_python_TARGET_NAME}.h\"
857 static PyMethodDef Py${_vtk_python_static_importer_name}_Methods[] = {
858 {NULL, NULL, 0, NULL}};
859 #if PY_VERSION_HEX >= 0x03000000
860 static PyModuleDef ${_vtk_python_static_importer_name}Module = {
861 PyModuleDef_HEAD_INIT,
862 \
"${_vtk_python_static_importer_name}\", // m_name
863 \"module to import static components for ${_vtk_python_TARGET_NAME}\", // m_doc
865 Py${_vtk_python_static_importer_name}_Methods, // m_methods
873 #if PY_VERSION_HEX >= 0x03000000
874 PyMODINIT_FUNC PyInit_${_vtk_python_static_importer_name}(void)
876 PyMODINIT_FUNC init${_vtk_python_static_importer_name}(void)
879 // since this gets called after `Py_Initialize`, this will import the static
880 // modules and not just update the init table.
881 ${_vtk_python_TARGET_NAME}_load();
882 #if PY_VERSION_HEX >= 0x03000000
883 return PyModule_Create(&${_vtk_python_static_importer_name}Module);
885 Py_InitModule(\"${_vtk_python_static_importer_name}\", Py${_vtk_python_static_importer_name}_Methods);
889 # TODO: Install
this header.
891 OUTPUT
"${_vtk_python_static_importer_file}"
892 CONTENT
"${_vtk_python_static_importer_content}")
894 add_library(
"${_vtk_python_static_importer_name}" MODULE
895 ${_vtk_python_static_importer_file})
896 if (WIN32 AND NOT CYGWIN)
897 set_property(TARGET
"${_vtk_python_static_importer_name}"
901 set_property(TARGET "${_vtk_python_static_importer_name}
"
903 LIBRARY_OUTPUT_DIRECTORY "${_vtk_python_MODULE_DESTINATION}
")
904 get_property(_vtk_python_is_multi_config GLOBAL
905 PROPERTY GENERATOR_IS_MULTI_CONFIG)
906 if (_vtk_python_is_multi_config)
907 # XXX(MultiNinja): This isn't going to work in general since MultiNinja
908 # will error about overlapping output paths.
909 foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
910 string(TOUPPER "${_vtk_python_config}
" _vtk_python_config_upper)
911 set_property(TARGET "${_vtk_python_static_importer_name}
"
913 "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}
" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}
")
916 set_property(TARGET "${_vtk_python_static_importer_name}
"
919 target_link_libraries("${_vtk_python_static_importer_name}
"
921 ${_vtk_python_TARGET_NAME}
922 VTK::WrappingPythonCore
925 TARGETS "${_vtk_python_static_importer_name}
"
926 COMPONENT "${_vtk_python_COMPONENT}
"
927 RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}
"
928 LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}
"
929 ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}
")
930 endif () # if (_vtk_python_BUILD_STATIC)
935 @ingroup module-wrapping-python
936 @brief Install Python packages with a module
938 Some modules may have associated Python code. This function should be used to
942 vtk_module_add_python_package(<module>
945 [MODULE_DESTINATION <destination>]
946 [COMPONENT <component>])
949 The `<module>` argument must match the associated VTK module that the package
950 is with. Each package is independent and should be installed separately. That
951 is, `package` and `package.subpackage` should each get their own call to this
954 * `PACKAGE`: (Required) The package installed by this call. Currently,
955 subpackages must have their own call to this function.
956 * `FILES`: (Required) File paths should be relative to the source directory
957 of the calling `CMakeLists.txt`. Upward paths are not supported (nor are
958 checked for). Absolute paths are assumed to be in the build tree and their
959 relative path is computed relative to the current binary directory.
960 * `MODULE_DESTINATION`: Modules will be placed in this location in the
961 build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
962 currently does not. See `vtk_module_python_default_destination` for the
964 * `COMPONENT`: Defaults to `python`. All install rules created by this
965 function will use this installation component.
967 A `<module>-<package>` target is created which ensures that all Python modules
968 have been copied to the correct location in the build tree.
970 @todo Support a tree of modules with a single call.
972 @todo Support freezing the Python package. This should create a header and the
973 associated target should provide an interface for including this header. The
974 target should then be exported and the header installed properly.
976 function (vtk_module_add_python_package name)
977 if (NOT name STREQUAL _vtk_build_module)
979 "Python modules must match their module names.
")
982 cmake_parse_arguments(_vtk_add_python_package
984 "PACKAGE;MODULE_DESTINATION;COMPONENT
"
988 if (_vtk_add_python_package_UNPARSED_ARGUMENTS)
991 "${_vtk_add_python_package_UNPARSED_ARGUMENTS}
")
994 if (NOT _vtk_add_python_package_PACKAGE)
996 "The `PACKAGE` argument is required.
")
998 string(REPLACE ".
" "/
" _vtk_add_python_package_path "${_vtk_add_python_package_PACKAGE}
")
1000 if (NOT _vtk_add_python_package_FILES)
1002 "The `FILES` argument is required.
")
1005 if (NOT DEFINED _vtk_add_python_package_MODULE_DESTINATION)
1006 vtk_module_python_default_destination(_vtk_add_python_package_MODULE_DESTINATION)
1009 if (NOT DEFINED _vtk_add_python_package_COMPONENT)
1010 set(_vtk_add_python_package_COMPONENT "python
")
1013 set(_vtk_add_python_package_file_outputs)
1014 foreach (_vtk_add_python_package_file IN LISTS _vtk_add_python_package_FILES)
1015 if (IS_ABSOLUTE "${_vtk_add_python_package_file}
")
1016 file(RELATIVE_PATH _vtk_add_python_package_name
1017 "${CMAKE_CURRENT_BINARY_DIR}
"
1018 "${_vtk_add_python_package_name}
")
1020 set(_vtk_add_python_package_name
1021 "${_vtk_add_python_package_file}
")
1022 set(_vtk_add_python_package_file
1023 "${CMAKE_CURRENT_SOURCE_DIR}/${_vtk_add_python_package_file}
")
1026 set(_vtk_add_python_package_file_output
1027 "${CMAKE_BINARY_DIR}/${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_name}
")
1029 OUTPUT "${_vtk_add_python_package_file_output}
"
1030 DEPENDS "${_vtk_add_python_package_file}
"
1031 COMMAND "${CMAKE_COMMAND}
" -E copy_if_different
1032 "${_vtk_add_python_package_file}
"
1033 "${_vtk_add_python_package_file_output}
"
1034 COMMENT "Copying ${_vtk_add_python_package_name} to the binary directory
")
1035 list(APPEND _vtk_add_python_package_file_outputs
1036 "${_vtk_add_python_package_file_output}
")
1038 if (BUILD_SHARED_LIBS)
1040 FILES "${_vtk_add_python_package_name}
"
1041 DESTINATION "${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_path}
"
1042 COMPONENT "${_vtk_add_python_package_COMPONENT}
")
1046 get_property(_vtk_add_python_package_module GLOBAL
1047 PROPERTY "_vtk_module_${_vtk_build_module}_target_name
")
1048 add_custom_target("${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}
" ALL
1050 ${_vtk_add_python_package_file_outputs})
1052 # Set `python_modules` to provide the list of python files that go along with
1054 set_property(TARGET "${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}
"
1056 "python_modules
" "${_vtk_add_python_package_file_outputs}
")
1060 @ingroup module-wrapping-python
1061 @brief Use a Python package as a module
1063 If a module is a Python package, this function should be used instead of
1064 @ref vtk_module_add_module.
1067 vtk_module_add_python_module(<name>
1068 PACKAGES <packages>...)
1071 * `PACKAGES`: (Required) The list of packages installed by this module.
1072 These must have been created by the @ref vtk_module_add_python_package
1075 function (vtk_module_add_python_module name)
1076 if (NOT name STREQUAL _vtk_build_module)
1078 "Python modules must match their module names.
")
1081 cmake_parse_arguments(_vtk_add_python_module
1087 if (_vtk_add_python_module_UNPARSED_ARGUMENTS)
1090 "${_vtk_add_python_module_UNPARSED_ARGUMENTS}
")
1093 get_property(_vtk_add_python_module_depends GLOBAL
1094 PROPERTY "_vtk_module_${_vtk_build_module}_depends
")
1095 get_property(_vtk_add_python_module_target_name GLOBAL
1096 PROPERTY "_vtk_module_${_vtk_build_module}_target_name
")
1097 add_library("${_vtk_add_python_module_target_name}
" INTERFACE)
1098 target_link_libraries("${_vtk_add_python_module_target_name}
"
1100 ${_vtk_add_python_module_depends})
1101 if (NOT _vtk_build_module STREQUAL _vtk_add_python_module_target_name)
1102 add_library("${_vtk_build_module}
" ALIAS
1103 "${_vtk_add_python_module_target_name}
")
1105 foreach (_vtk_add_python_module_package IN LISTS _vtk_add_python_module_PACKAGES)
1106 add_dependencies("${_vtk_add_python_module_target_name}
"
1107 "${_vtk_build_module}-${_vtk_add_python_module_package}
")
1109 # get the list of python files and add them on the module.
1110 get_property(_vtk_module_python_modules
1111 TARGET "${_vtk_add_python_module_target_name}-${_vtk_add_python_module_package}
"
1112 PROPERTY "python_modules
")
1113 _vtk_module_set_module_property("${_vtk_build_module}
" APPEND
1114 PROPERTY "python_modules
"
1115 VALUE "${_vtk_module_python_modules}
")
1118 _vtk_module_apply_properties("${_vtk_add_python_module_target_name}
")
1119 _vtk_module_install("${_vtk_add_python_module_target_name}
")