VTK  9.2.6
vtkModuleWrapPython.cmake
Go to the documentation of this file.
1#[==[
2@defgroup module-wrapping-python Module Python CMake APIs
3#]==]
4
5#[==[
6@file vtkModuleWrapPython.cmake
7@brief APIs for wrapping modules for Python
8
9@section python-wrapping-limitations Limitations
10
11Known 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
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.
30
31~~~
32vtk_module_python_default_destination(<var>
33 [MAJOR_VERSION <major>])
34~~~
35
36By default, the destination is `${CMAKE_INSTALL_BINDIR}/Lib/site-packages` on
37Windows 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
40the value of `${VTK_PYTHON_VERSION}`.
41#]==]
42
43cmake_policy(PUSH)
44cmake_policy(SET CMP0053 NEW)
45
46function (vtk_module_python_default_destination var)
47 cmake_parse_arguments(PARSE_ARGV 1 _vtk_module_python
48 ""
49 "MAJOR_VERSION"
50 "")
51
52 if (_vtk_module_python_UNPARSED_ARGUMENTS)
53 message(FATAL_ERROR
54 "Unparsed arguments for vtk_module_python_default_destination: "
55 "${_vtk_module_python_UNPARSED_ARGUMENTS}")
56 endif ()
57
58 if (NOT _vtk_module_python_MAJOR_VERSION)
59 if (NOT DEFINED VTK_PYTHON_VERSION)
60 message(FATAL_ERROR
61 "A major version of Python must be specified (or `VTK_PYTHON_VERSION` "
62 "be set).")
63 endif ()
64
65 set(_vtk_module_python_MAJOR_VERSION "${VTK_PYTHON_VERSION}")
66 endif ()
67
68 if (NOT _vtk_module_python_MAJOR_VERSION STREQUAL "2" AND
69 NOT _vtk_module_python_MAJOR_VERSION STREQUAL "3")
70 message(FATAL_ERROR
71 "Only Python2 and Python3 are supported right now.")
72 endif ()
73
74 if (MSVC)
75 set(destination "${CMAKE_INSTALL_BINDIR}/Lib/site-packages")
76 else ()
77 if (NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR" OR
78 NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR")
79 find_package("Python${_vtk_module_python_MAJOR_VERSION}" QUIET COMPONENTS Development.Module)
80 endif ()
81
82 if (Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR AND Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR)
83 set(_vtk_python_version_suffix "${Python${VTK_PYTHON_VERSION}_VERSION_MAJOR}.${Python${VTK_PYTHON_VERSION}_VERSION_MINOR}")
84 else ()
85 message(WARNING
86 "The version of Python is unknown; not using a versioned directory "
87 "for Python modules.")
88 set(_vtk_python_version_suffix)
89 endif ()
90 set(destination "${CMAKE_INSTALL_LIBDIR}/python${_vtk_python_version_suffix}/site-packages")
91 endif ()
92
93 set("${var}" "${destination}" PARENT_SCOPE)
94endfunction ()
95
96#[==[
97@ingroup module-impl
98@brief Generate sources for using a module's classes from Python
99
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.
103
104~~~
105_vtk_module_wrap_python_sources(<module> <sources> <classes>)
106~~~
107#]==]
108function (_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}")
122 PROPERTY "private_depends"
123 VARIABLE _vtk_python_private_depends)
124 list(APPEND _vtk_python_hierarchy_depends
125 ${_vtk_python_private_depends})
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.
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)
230endfunction ()
231
232#[==[
233@ingroup module-impl
234@brief Generate a CPython library for a set of modules
235
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.
239
240~~~
241_vtk_module_wrap_python_library(<name> <module>...)
242~~~
243
244The first argument is the name of the Python module. The remaining arguments
245are modules to include in the Python module.
246
247The remaining information it uses is assumed to be provided by the
249#]==]
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
404extern \"C\" {
405#endif
406#if PY_VERSION_HEX < 0x03000000
407extern void init${_vtk_python_library_name}();
408#else
409extern 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
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}")
530endfunction ()
531
532#[==[
533@ingroup module-wrapping-python
534@brief Wrap a set of modules for use in Python
535
536~~~
537vtk_module_wrap_python(
538 MODULES <module>...
539 [TARGET <target>]
540 [WRAPPED_MODULES <varname>]
541
542 [BUILD_STATIC <ON|OFF>]
543 [INSTALL_HEADERS <ON|OFF>]
544 [BUILD_PYI_FILES <ON|OFF>]
545
546 [DEPENDS <target>...]
547 [UTILITY_TARGET <target>]
548
549 [MODULE_DESTINATION <destination>]
550 [STATIC_MODULE_DESTINATION <destination>]
551 [CMAKE_DESTINATION <destination>]
552 [LIBRARY_DESTINATION <destination>]
553
554 [PYTHON_PACKAGE <package>]
555 [SOABI <soabi>]
556 [USE_DEBUG_SUFFIX <ON|OFF>]
557
558 [INSTALL_EXPORT <export>]
559 [COMPONENT <component>])
560 [TARGET_SPECIFIC_COMPONENTS <ON|OFF>]
561~~~
562
563 * `MODULES`: (Required) The list of modules to wrap.
564 * `TARGET`: (Recommended) The target to create which represents all wrapped
565 Python modules. This is mostly useful when supporting static Python modules
566 in order to add the generated modules to the built-in table.
567 * `WRAPPED_MODULES`: (Recommended) Not all modules are wrappable. This
568 variable will be set to contain the list of modules which were wrapped.
569 These modules will have a `INTERFACE_vtk_module_python_package` property
570 set on them which is the name that should be given to `import` statements
571 in Python code.
572 * `BUILD_STATIC`: Defaults to `${BUILD_SHARED_LIBS}`. Note that shared
573 modules with a static build is not completely supported. For static Python
574 module builds, a header named `<TARGET>.h` will be available with a
575 function `void <TARGET>_load()` which will add all Python modules created
576 by this call to the imported module table. For shared Python module builds,
577 the same function is provided, but it is a no-op.
578 * `INSTALL_HEADERS` (Defaults to `ON`): If unset, CMake properties will not
579 be installed.
580 * `BUILD_PYI_FILES` (Defaults to `OFF`): If set, `.pyi` files will be built
581 and installed for the generated modules.
582 * `TARGET_SPECIFIC_COMPONENTS` (Defaults to `OFF`): If set, prepend the
583 output target name to the install component (`<TARGET>-<COMPONENT>`).
584 * `DEPENDS`: This is list of other Python modules targets i.e. targets
585 generated from previous calls to `vtk_module_wrap_python` that this new
586 target depends on. This is used when `BUILD_STATIC` is true to ensure that
587 the `void <TARGET>_load()` is correctly called for each of the dependencies.
588 * `UTILITY_TARGET`: If specified, all libraries made by the Python wrapping
589 will link privately to this target. This may be used to add compile flags
590 to the Python libraries.
591 * `MODULE_DESTINATION`: Modules will be placed in this location in the
592 build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
593 currently does not. See `vtk_module_python_default_destination` for the
594 default value.
595 * `STATIC_MODULE_DESTINATION`: Defaults to `${CMAKE_INSTALL_LIBDIR}`. This
596 default may change in the future since the best location for these files is
597 not yet known. Static libraries containing Python code will be installed to
598 the install tree under this path.
599 * `CMAKE_DESTINATION`: (Required if `INSTALL_HEADERS` is `ON`) Where to
600 install Python-related module property CMake files.
601 * `LIBRARY_DESTINATION` (Recommended): If provided, dynamic loader
602 information will be added to modules for loading dependent libraries.
603 * `PYTHON_PACKAGE`: (Recommended) All generated modules will be added to this
604 Python package. The format is in Python syntax (e.g.,
605 `package.subpackage`).
606 * `SOABI`: (Required for wheel support): If given, generate libraries with
607 the SOABI tag in the module filename.
608 * `USE_DEBUG_SUFFIX` (Defaults to `OFF`): If `ON`, Windows modules will have
609 a `_d` suffix appended to the module name. This is intended for use with
610 debug Python builds.
611 * `INSTALL_EXPORT`: If provided, static installs will add the installed
612 libraries to the provided export set.
613 * `COMPONENT`: Defaults to `python`. All install rules created by this
614 function will use this installation component.
615#]==]
617 cmake_parse_arguments(PARSE_ARGV 0 _vtk_python
618 ""
619 "MODULE_DESTINATION;STATIC_MODULE_DESTINATION;LIBRARY_DESTINATION;PYTHON_PACKAGE;BUILD_STATIC;INSTALL_HEADERS;INSTALL_EXPORT;TARGET_SPECIFIC_COMPONENTS;TARGET;COMPONENT;WRAPPED_MODULES;CMAKE_DESTINATION;SOABI;USE_DEBUG_SUFFIX;UTILITY_TARGET;BUILD_PYI_FILES"
620 "DEPENDS;MODULES")
621
622 if (_vtk_python_UNPARSED_ARGUMENTS)
623 message(FATAL_ERROR
624 "Unparsed arguments for vtk_module_wrap_python: "
625 "${_vtk_python_UNPARSED_ARGUMENTS}")
626 endif ()
627
628 if (NOT _vtk_python_MODULES)
629 message(WARNING
630 "No modules were requested for Python wrapping.")
631 return ()
632 endif ()
633
634 _vtk_module_split_module_name("${_vtk_python_TARGET}" _vtk_python)
635
636 set(_vtk_python_depends)
637 foreach (_vtk_python_depend IN LISTS _vtk_python_DEPENDS)
638 _vtk_module_split_module_name("${_vtk_python_depend}" _vtk_python_depends)
639 list(APPEND _vtk_python_depends
640 "${_vtk_python_depends_TARGET_NAME}")
641 endforeach ()
642
643 if (NOT DEFINED _vtk_python_MODULE_DESTINATION)
644 vtk_module_python_default_destination(_vtk_python_MODULE_DESTINATION)
645 endif ()
646
647 if (NOT DEFINED _vtk_python_INSTALL_HEADERS)
648 set(_vtk_python_INSTALL_HEADERS ON)
649 endif ()
650
651 if (NOT DEFINED _vtk_python_BUILD_PYI_FILES)
652 set(_vtk_python_BUILD_PYI_FILES OFF)
653 endif ()
654
655 if (NOT DEFINED _vtk_python_TARGET_SPECIFIC_COMPONENTS)
656 set(_vtk_python_TARGET_SPECIFIC_COMPONENTS OFF)
657 endif ()
658
659 if (NOT DEFINED _vtk_python_USE_DEBUG_SUFFIX)
660 set(_vtk_python_USE_DEBUG_SUFFIX OFF)
661 endif ()
662
663 if (_vtk_python_SOABI)
664 get_property(_vtk_python_is_multi_config GLOBAL
665 PROPERTY GENERATOR_IS_MULTI_CONFIG)
666 if (_vtk_python_is_multi_config)
667 foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
668 string(TOUPPER "${_vtk_python_config}" _vtk_python_upper_config)
669 set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
670 ".${_vtk_python_SOABI}")
671 endforeach ()
672 else ()
673 string(TOUPPER "${CMAKE_BUILD_TYPE}" _vtk_python_upper_config)
674 set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
675 ".${_vtk_python_SOABI}")
676 endif ()
677 endif ()
678
679 if (_vtk_python_INSTALL_HEADERS AND NOT DEFINED _vtk_python_CMAKE_DESTINATION)
680 message(FATAL_ERROR
681 "No CMAKE_DESTINATION set, but headers from the Python wrapping were "
682 "requested for install and the CMake files are required to work with "
683 "them.")
684 endif ()
685
686 if (NOT DEFINED _vtk_python_BUILD_STATIC)
687 if (BUILD_SHARED_LIBS)
688 set(_vtk_python_BUILD_STATIC OFF)
689 else ()
690 set(_vtk_python_BUILD_STATIC ON)
691 endif ()
692 else ()
693 if (NOT _vtk_python_BUILD_STATIC AND NOT BUILD_SHARED_LIBS)
694 message(WARNING
695 "Building shared Python modules against static VTK modules only "
696 "supports consuming the VTK modules via their Python interfaces due "
697 "to the lack of support for an SDK to use the same static libraries.")
698 endif ()
699 endif ()
700
701 if (NOT DEFINED _vtk_python_STATIC_MODULE_DESTINATION)
702 # TODO: Is this correct?
703 set(_vtk_python_STATIC_MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}")
704 endif ()
705
706 if (NOT DEFINED _vtk_python_COMPONENT)
707 set(_vtk_python_COMPONENT "python")
708 endif ()
709
710 if (NOT _vtk_python_PYTHON_PACKAGE)
711 message(FATAL_ERROR
712 "No `PYTHON_PACKAGE` was given; Python modules must be placed into a "
713 "package.")
714 endif ()
715 string(REPLACE "." "/" _vtk_python_package_path "${_vtk_python_PYTHON_PACKAGE}")
716
717 if(_vtk_python_BUILD_STATIC)
718 # When doing static builds we want the statically initialized built-ins to be
719 # used. It is unclear in the Python-C API how to construct `namespace.module`
720 # so instead at the C++ level we import "namespace_module" during startup
721 # and than the python modules moving those imports into the correct python
722 # module.
723 string(REPLACE "." "_" _vtk_python_import_prefix "${_vtk_python_PYTHON_PACKAGE}_")
724 else()
725 # We are building dynamic libraries therefore the prefix is simply '.'
726 set(_vtk_python_import_prefix ".")
727 endif()
728
730 MODULE_DESTINATION
731 STATIC_MODULE_DESTINATION
732 CMAKE_DESTINATION
733 LIBRARY_DESTINATION)
734
735 if (_vtk_python_INSTALL_HEADERS)
736 set(_vtk_python_properties_filename "${_vtk_python_PYTHON_PACKAGE}-vtk-python-module-properties.cmake")
737 set(_vtk_python_properties_install_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/${_vtk_python_properties_filename}.install")
738 set(_vtk_python_properties_build_file "${CMAKE_BINARY_DIR}/${_vtk_python_CMAKE_DESTINATION}/${_vtk_python_properties_filename}")
739
740 file(WRITE "${_vtk_python_properties_build_file}")
741 file(WRITE "${_vtk_python_properties_install_file}")
742 endif ()
743
744 if (DEFINED _vtk_python_LIBRARY_DESTINATION)
745 # Set up rpaths
746 set(CMAKE_BUILD_RPATH_USE_ORIGIN 1)
747 if (UNIX)
748 file(RELATIVE_PATH _vtk_python_relpath
749 "/prefix/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
750 "/prefix/${_vtk_python_LIBRARY_DESTINATION}")
751
752 if (APPLE)
753 set(_vtk_python_origin_stem "@loader_path")
754 else ()
755 set(_vtk_python_origin_stem "$ORIGIN")
756 endif()
757
758 list(APPEND CMAKE_INSTALL_RPATH
759 "${_vtk_python_origin_stem}/${_vtk_python_relpath}")
760 endif ()
761 endif ()
762
763 set(_vtk_python_sorted_modules ${_vtk_python_MODULES})
764 foreach (_vtk_python_module IN LISTS _vtk_python_MODULES)
765 _vtk_module_get_module_property("${_vtk_python_module}"
766 PROPERTY "depends"
767 VARIABLE "_vtk_python_${_vtk_python_module}_depends")
768 endforeach ()
769 vtk_topological_sort(_vtk_python_sorted_modules "_vtk_python_" "_depends")
770
771 set(_vtk_python_sorted_modules_filtered)
772 foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules)
773 if (_vtk_python_module IN_LIST _vtk_python_MODULES)
774 list(APPEND _vtk_python_sorted_modules_filtered
775 "${_vtk_python_module}")
776 endif ()
777 endforeach ()
778
779 set(_vtk_python_headers_component "development")
780 set(_vtk_python_component "${_vtk_python_COMPONENT}")
781 if (_vtk_python_TARGET_SPECIFIC_COMPONENTS)
782 string(PREPEND _vtk_python_headers_component "${_vtk_python_TARGET_NAME}-")
783 string(PREPEND _vtk_python_component "${_vtk_python_TARGET_NAME}-")
784 endif ()
785
786 # Disable CMake's automoc support for these targets.
787 set(CMAKE_AUTOMOC 0)
788 set(CMAKE_AUTORCC 0)
789 set(CMAKE_AUTOUIC 0)
790
791 set(_vtk_python_all_modules)
792 set(_vtk_python_all_wrapped_modules)
793 foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
794 _vtk_module_get_module_property("${_vtk_python_module}"
795 PROPERTY "library_name"
796 VARIABLE _vtk_python_library_name)
797 _vtk_module_wrap_python_library("${_vtk_python_library_name}Python" "${_vtk_python_module}")
798
799 if (TARGET "${_vtk_python_library_name}Python")
800 list(APPEND _vtk_python_all_modules
801 "${_vtk_python_library_name}Python")
802 list(APPEND _vtk_python_all_wrapped_modules
803 "${_vtk_python_module}")
804 endif ()
805 endforeach ()
806
807 if (NOT _vtk_python_all_modules)
808 message(FATAL_ERROR
809 "No modules given could be wrapped.")
810 endif ()
811
812 if (_vtk_python_INSTALL_HEADERS)
813 install(
814 FILES "${_vtk_python_properties_install_file}"
815 DESTINATION "${_vtk_python_CMAKE_DESTINATION}"
816 RENAME "${_vtk_python_properties_filename}"
817 COMPONENT "${_vtk_python_headers_component}")
818 endif ()
819
820 if (DEFINED _vtk_python_WRAPPED_MODULES)
821 set("${_vtk_python_WRAPPED_MODULES}"
822 "${_vtk_python_all_wrapped_modules}"
823 PARENT_SCOPE)
824 endif ()
825
826 if (_vtk_python_TARGET)
827 add_library("${_vtk_python_TARGET_NAME}" INTERFACE)
828 target_include_directories("${_vtk_python_TARGET_NAME}"
829 INTERFACE
830 "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python>")
831 target_link_libraries("${_vtk_python_TARGET_NAME}"
832 INTERFACE
833 ${_vtk_python_DEPENDS})
834 if (NOT _vtk_python_TARGET STREQUAL _vtk_python_TARGET_NAME)
835 add_library("${_vtk_python_TARGET}" ALIAS
836 "${_vtk_python_TARGET_NAME}")
837 endif ()
838
839 if (_vtk_python_INSTALL_EXPORT)
840 install(
841 TARGETS "${_vtk_python_TARGET_NAME}"
842 EXPORT "${_vtk_python_INSTALL_EXPORT}"
843 COMPONENT "${_vtk_python_headers_component}")
844 endif ()
845
846 set(_vtk_python_all_modules_include_file
847 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_TARGET_NAME}.h")
848 set(_vtk_python_all_modules_include_content
849 "#ifndef ${_vtk_python_TARGET_NAME}_h\n#define ${_vtk_python_TARGET_NAME}_h\n")
850
851 if (_vtk_python_BUILD_STATIC)
852 foreach (_vtk_python_module IN LISTS _vtk_python_all_modules)
853 string(APPEND _vtk_python_all_modules_include_content
854 "#include \"${_vtk_python_module}.h\"\n")
855 endforeach ()
856 endif ()
857
858 foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
859 string(APPEND _vtk_python_all_modules_include_content
860 "#include \"${_vtk_python_depend}.h\"\n")
861 endforeach ()
862
863 string(APPEND _vtk_python_all_modules_include_content
864"#if PY_VERSION_HEX < 0x03000000
865#define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, init ## module)
866#define PY_IMPORT(module) init ## module();
867#else
868#define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, PyInit_ ## module)
869#define PY_IMPORT(module) { \\
870 PyObject* var_ ## module = PyInit_ ## module(); \\
871 PyDict_SetItemString(PyImport_GetModuleDict(), \"${_vtk_python_import_prefix}\" #module,var_ ## module); \\
872 Py_DECREF(var_ ## module); }
873#endif
874
875#define PY_APPEND_INIT_OR_IMPORT(module, do_import) \\
876 if (do_import) { PY_IMPORT(module); } else { PY_APPEND_INIT(module); }
877
878static void ${_vtk_python_TARGET_NAME}_load() {\n")
879
880 foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
881 string(APPEND _vtk_python_all_modules_include_content
882 " ${_vtk_python_depend}_load();\n")
883 endforeach ()
884
885 if (_vtk_python_BUILD_STATIC)
886 string(APPEND _vtk_python_all_modules_include_content
887 " int do_import = Py_IsInitialized();\n")
888 foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
889 _vtk_module_get_module_property("${_vtk_python_module}"
890 PROPERTY "library_name"
891 VARIABLE _vtk_python_library_name)
892 if (TARGET "${_vtk_python_library_name}Python")
893 string(APPEND _vtk_python_all_modules_include_content
894 " PY_APPEND_INIT_OR_IMPORT(${_vtk_python_library_name}, do_import);\n")
895 endif ()
896 endforeach ()
897 endif ()
898
899 string(APPEND _vtk_python_all_modules_include_content
900 "}\n#undef PY_APPEND_INIT\n#undef PY_IMPORT\n#undef PY_APPEND_INIT_OR_IMPORT\n#endif\n")
901
902 # TODO: Install this header.
903 file(GENERATE
904 OUTPUT "${_vtk_python_all_modules_include_file}"
905 CONTENT "${_vtk_python_all_modules_include_content}")
906
907 if (_vtk_python_BUILD_STATIC)
908 # TODO: Install these targets.
909 target_link_libraries("${_vtk_python_TARGET_NAME}"
910 INTERFACE
911 ${_vtk_python_all_modules})
912 endif ()
913
914 if (_vtk_python_BUILD_STATIC)
915 # Next, we generate a Python module that can be imported to import any
916 # static artifacts e.g. all wrapping Python modules in static builds,
917 # (eventually, frozen modules etc.)
918 string(REPLACE "." "_" _vtk_python_static_importer_name "_${_vtk_python_PYTHON_PACKAGE}_static")
919 set(_vtk_python_static_importer_file
920 "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_static_importer_name}.c")
921 set(_vtk_python_static_importer_content "// generated file, do not edit!
922#include <vtkPython.h>
923#include \"${_vtk_python_TARGET_NAME}.h\"
924
925 static PyMethodDef Py${_vtk_python_static_importer_name}_Methods[] = {
926 {NULL, NULL, 0, NULL}};
927#if PY_VERSION_HEX >= 0x03000000
928 static PyModuleDef ${_vtk_python_static_importer_name}Module = {
929 PyModuleDef_HEAD_INIT,
930 \"${_vtk_python_static_importer_name}\", // m_name
931 \"module to import static components for ${_vtk_python_TARGET_NAME}\", // m_doc
932 0, // m_size
933 Py${_vtk_python_static_importer_name}_Methods, // m_methods
934 NULL, // m_reload
935 NULL, // m_traverse
936 NULL, // m_clear
937 NULL // m_free
938 };
939#endif
940
941#if PY_VERSION_HEX >= 0x03000000
942 PyMODINIT_FUNC PyInit_${_vtk_python_static_importer_name}(void)
943#else
944 PyMODINIT_FUNC init${_vtk_python_static_importer_name}(void)
945#endif
946 {
947 // since this gets called after `Py_Initialize`, this will import the static
948 // modules and not just update the init table.
949 ${_vtk_python_TARGET_NAME}_load();
950#if PY_VERSION_HEX >= 0x03000000
951 return PyModule_Create(&${_vtk_python_static_importer_name}Module);
952#else
953 Py_InitModule(\"${_vtk_python_static_importer_name}\", Py${_vtk_python_static_importer_name}_Methods);
954#endif
955 }\n")
956
957 # TODO: Install this header.
958 file(GENERATE
959 OUTPUT "${_vtk_python_static_importer_file}"
960 CONTENT "${_vtk_python_static_importer_content}")
961
962 add_library("${_vtk_python_static_importer_name}" MODULE
963 ${_vtk_python_static_importer_file})
964 if (WIN32 AND NOT CYGWIN)
965 set_property(TARGET "${_vtk_python_static_importer_name}"
966 PROPERTY
967 SUFFIX ".pyd")
968 endif()
969 set_property(TARGET "${_vtk_python_static_importer_name}"
970 PROPERTY
971 LIBRARY_OUTPUT_DIRECTORY "${_vtk_python_MODULE_DESTINATION}")
972 get_property(_vtk_python_is_multi_config GLOBAL
973 PROPERTY GENERATOR_IS_MULTI_CONFIG)
974 if (_vtk_python_is_multi_config)
975 # XXX(MultiNinja): This isn't going to work in general since MultiNinja
976 # will error about overlapping output paths.
977 foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
978 string(TOUPPER "${_vtk_python_config}" _vtk_python_config_upper)
979 set_property(TARGET "${_vtk_python_static_importer_name}"
980 PROPERTY
981 "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}")
982 endforeach ()
983 endif ()
984 set_property(TARGET "${_vtk_python_static_importer_name}"
985 PROPERTY
986 PREFIX "")
987 target_link_libraries("${_vtk_python_static_importer_name}"
988 PRIVATE
989 ${_vtk_python_TARGET_NAME}
990 VTK::WrappingPythonCore
991 VTK::Python)
992
993 install(
994 TARGETS "${_vtk_python_static_importer_name}"
995 COMPONENT "${_vtk_python_component}"
996 RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}"
997 LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}"
998 ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}")
999 endif () # if (_vtk_python_BUILD_STATIC)
1000
1001 # convert package "x.y" into "x/y" to access its contents on the filesystem
1002 string(REPLACE "." "/" _vtk_python_package_dir "${_vtk_python_PYTHON_PACKAGE}")
1003
1004 if (_vtk_python_BUILD_PYI_FILES)
1005 set(_vtk_python_pyi_files)
1006 set(_vtk_python_modules)
1007 set(_vtk_python_module_targets)
1008 foreach (_vtk_python_module IN LISTS _vtk_python_all_wrapped_modules)
1009 get_property(_vtk_python_library_name
1010 TARGET "${_vtk_python_module}"
1011 PROPERTY "INTERFACE_vtk_module_library_name")
1012 list(APPEND _vtk_python_pyi_files
1013 "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_dir}/${_vtk_python_library_name}.pyi")
1014 list(APPEND _vtk_python_modules "${_vtk_python_library_name}")
1015 if (TARGET "${_vtk_python_library_name}Python")
1016 list(APPEND _vtk_python_module_targets "${_vtk_python_library_name}Python")
1017 endif ()
1018 endforeach ()
1019
1020 if (TARGET VTK::vtkpython)
1021 set(_vtk_python_exe $<TARGET_FILE:VTK::vtkpython>)
1022 else ()
1023 set(_vtk_python_exe "${Python3_EXECUTABLE}")
1024 endif ()
1025
1026 # XXX(python2): Remove this conditional
1027 if (NOT VTK_PYTHON_VERSION STREQUAL "2")
1028 add_custom_command(
1029 OUTPUT ${_vtk_python_pyi_files}
1030 COMMAND "${_vtk_python_exe}"
1031 -m vtkmodules.generate_pyi
1032 -p "${_vtk_python_PYTHON_PACKAGE}"
1033 -o "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_dir}"
1034 ${_vtk_python_modules}
1035 WORKING_DIRECTORY
1036 "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}"
1037 DEPENDS ${_vtk_python_module_targets}
1038 ${_vtk_python_static_importer_name}
1039 "${_vtk_pyi_script}"
1040 COMMENT "Creating .pyi files for ${_vtk_python_TARGET_NAME}")
1041
1042 install(
1043 FILES ${_vtk_python_pyi_files}
1044 DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_dir}"
1045 COMPONENT "${_vtk_python_component}")
1046
1047 add_custom_target("${_vtk_python_TARGET_NAME}_pyi" ALL
1048 DEPENDS ${_vtk_python_pyi_files})
1049 endif ()
1050 endif ()
1051 endif ()
1052endfunction ()
1053
1054#[==[
1055@ingroup module-wrapping-python
1056@brief Install Python packages with a module
1057
1058Some modules may have associated Python code. This function should be used to
1059install them.
1060
1061~~~
1063 PACKAGE <package>
1064 FILES <files>...
1065 [MODULE_DESTINATION <destination>]
1066 [COMPONENT <component>])
1067~~~
1068
1069The `<module>` argument must match the associated VTK module that the package
1070is with. Each package is independent and should be installed separately. That
1071is, `package` and `package.subpackage` should each get their own call to this
1072function.
1073
1074 * `PACKAGE`: (Required) The package installed by this call. Currently,
1075 subpackages must have their own call to this function.
1076 * `FILES`: (Required) File paths should be relative to the source directory
1077 of the calling `CMakeLists.txt`. Upward paths are not supported (nor are
1078 checked for). Absolute paths are assumed to be in the build tree and their
1079 relative path is computed relative to the current binary directory.
1080 * `MODULE_DESTINATION`: Modules will be placed in this location in the
1081 build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
1082 currently does not. See `vtk_module_python_default_destination` for the
1083 default value.
1084 * `COMPONENT`: Defaults to `python`. All install rules created by this
1085 function will use this installation component.
1086
1087A `<module>-<package>` target is created which ensures that all Python modules
1088have been copied to the correct location in the build tree.
1089
1090@todo Support freezing the Python package. This should create a header and the
1091associated target should provide an interface for including this header. The
1092target should then be exported and the header installed properly.
1093#]==]
1095 if (NOT name STREQUAL _vtk_build_module)
1096 message(FATAL_ERROR
1097 "Python modules must match their module names.")
1098 endif ()
1099
1100 cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_package
1101 ""
1102 "PACKAGE;MODULE_DESTINATION;COMPONENT"
1103 "FILES")
1104
1105 if (_vtk_add_python_package_UNPARSED_ARGUMENTS)
1106 message(FATAL_ERROR
1107 "Unparsed arguments for vtk_module_add_python_package: "
1108 "${_vtk_add_python_package_UNPARSED_ARGUMENTS}")
1109 endif ()
1110
1111 if (NOT _vtk_add_python_package_PACKAGE)
1112 message(FATAL_ERROR
1113 "The `PACKAGE` argument is required.")
1114 endif ()
1115 string(REPLACE "." "/" _vtk_add_python_package_path "${_vtk_add_python_package_PACKAGE}")
1116
1117 if (NOT _vtk_add_python_package_FILES)
1118 message(FATAL_ERROR
1119 "The `FILES` argument is required.")
1120 endif ()
1121
1122 if (NOT DEFINED _vtk_add_python_package_MODULE_DESTINATION)
1123 vtk_module_python_default_destination(_vtk_add_python_package_MODULE_DESTINATION)
1124 endif ()
1125
1126 if (NOT DEFINED _vtk_add_python_package_COMPONENT)
1127 set(_vtk_add_python_package_COMPONENT "python")
1128 endif ()
1129
1130 set(_vtk_add_python_package_file_outputs)
1131 foreach (_vtk_add_python_package_file IN LISTS _vtk_add_python_package_FILES)
1132 if (IS_ABSOLUTE "${_vtk_add_python_package_file}")
1133 file(RELATIVE_PATH _vtk_add_python_package_name
1134 "${CMAKE_CURRENT_BINARY_DIR}"
1135 "${_vtk_add_python_package_file}")
1136 else ()
1137 set(_vtk_add_python_package_name
1138 "${_vtk_add_python_package_file}")
1139 string(PREPEND _vtk_add_python_package_file
1140 "${CMAKE_CURRENT_SOURCE_DIR}/")
1141 endif ()
1142
1143 set(_vtk_add_python_package_file_output
1144 "${CMAKE_BINARY_DIR}/${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_name}")
1145 add_custom_command(
1146 OUTPUT "${_vtk_add_python_package_file_output}"
1147 DEPENDS "${_vtk_add_python_package_file}"
1148 COMMAND "${CMAKE_COMMAND}" -E copy_if_different
1149 "${_vtk_add_python_package_file}"
1150 "${_vtk_add_python_package_file_output}"
1151 COMMENT "Copying ${_vtk_add_python_package_name} to the binary directory")
1152 list(APPEND _vtk_add_python_package_file_outputs
1153 "${_vtk_add_python_package_file_output}")
1154 if (BUILD_SHARED_LIBS)
1155 get_filename_component(_vtk_add_python_package_install_path "${_vtk_add_python_package_name}" DIRECTORY)
1156 install(
1157 FILES "${_vtk_add_python_package_name}"
1158 DESTINATION "${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_install_path}"
1159 COMPONENT "${_vtk_add_python_package_COMPONENT}")
1160 endif()
1161 endforeach ()
1162
1163 get_property(_vtk_add_python_package_module GLOBAL
1164 PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
1165 add_custom_target("${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}" ALL
1166 DEPENDS
1167 ${_vtk_add_python_package_file_outputs})
1168
1169 # Set `python_modules` to provide the list of python files that go along with
1170 # this module
1171 set_property(TARGET "${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}"
1172 PROPERTY
1173 "python_modules" "${_vtk_add_python_package_file_outputs}")
1174endfunction ()
1175
1176#[==[
1177@ingroup module-wrapping-python
1178@brief Use a Python package as a module
1179
1180If a module is a Python package, this function should be used instead of
1182
1183~~~
1185 PACKAGES <packages>...)
1186~~~
1187
1188 * `PACKAGES`: (Required) The list of packages installed by this module.
1189 These must have been created by the @ref vtk_module_add_python_package
1190 function.
1191#]==]
1193 if (NOT name STREQUAL _vtk_build_module)
1194 message(FATAL_ERROR
1195 "Python modules must match their module names.")
1196 endif ()
1197
1198 cmake_parse_arguments(PARSE_ARGV 1 _vtk_add_python_module
1199 ""
1200 ""
1201 "PACKAGES")
1202
1203 if (_vtk_add_python_module_UNPARSED_ARGUMENTS)
1204 message(FATAL_ERROR
1205 "Unparsed arguments for vtk_module_add_python_module: "
1206 "${_vtk_add_python_module_UNPARSED_ARGUMENTS}")
1207 endif ()
1208
1209 get_property(_vtk_add_python_module_depends GLOBAL
1210 PROPERTY "_vtk_module_${_vtk_build_module}_depends")
1211 get_property(_vtk_add_python_module_target_name GLOBAL
1212 PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
1213 add_library("${_vtk_add_python_module_target_name}" INTERFACE)
1214 target_link_libraries("${_vtk_add_python_module_target_name}"
1215 INTERFACE
1216 ${_vtk_add_python_module_depends})
1217 if (NOT _vtk_build_module STREQUAL _vtk_add_python_module_target_name)
1218 add_library("${_vtk_build_module}" ALIAS
1219 "${_vtk_add_python_module_target_name}")
1220 endif ()
1221 foreach (_vtk_add_python_module_package IN LISTS _vtk_add_python_module_PACKAGES)
1222 add_dependencies("${_vtk_add_python_module_target_name}"
1223 "${_vtk_build_module}-${_vtk_add_python_module_package}")
1224
1225 # get the list of python files and add them on the module.
1226 get_property(_vtk_module_python_modules
1227 TARGET "${_vtk_add_python_module_target_name}-${_vtk_add_python_module_package}"
1228 PROPERTY "python_modules")
1229 _vtk_module_set_module_property("${_vtk_build_module}" APPEND
1230 PROPERTY "python_modules"
1231 VALUE "${_vtk_module_python_modules}")
1232 endforeach ()
1233
1234 get_property(_vtk_add_python_module_LICENSE_FILES GLOBAL
1235 PROPERTY "_vtk_module_${_vtk_build_module}_license_files")
1236 if (_vtk_add_python_module_LICENSE_FILES)
1237 if (_vtk_build_TARGET_SPECIFIC_COMPONENTS)
1238 string(PREPEND _vtk_build_LICENSE_COMPONENT "${_vtk_build_module}-")
1239 endif ()
1240 install(
1241 FILES ${_vtk_add_python_module_LICENSE_FILES}
1242 DESTINATION "${_vtk_build_LICENSE_DESTINATION}/${_vtk_add_python_module_target_name}/"
1243 COMPONENT "${_vtk_build_LICENSE_COMPONENT}")
1244 endif ()
1245
1246 _vtk_module_apply_properties("${_vtk_add_python_module_target_name}")
1247 _vtk_module_install("${_vtk_add_python_module_target_name}")
1248endfunction ()
1249
1250cmake_policy(POP)
Computes the portion of a dataset which is inside a selection.
function _vtk_module_wrap_python_sources(module, sources, classes)
Generate sources for using a module's classes from Python.
function _vtk_module_wrap_python_library(name)
Generate a CPython library for a set of modules.
function _vtk_module_apply_properties(target)
Apply properties to a module.
function _vtk_module_real_target(var, module)
The real target for a module.
function _vtk_module_check_destinations(prefix)
Check that destinations are valid.
function _vtk_module_split_module_name(name, prefix)
Split a module name into a namespace and target component.
function _vtk_module_install(target)
Install a module target.
function _vtk_module_set_module_property(module)
Set a module property.
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_python_default_destination(var)
Determine Python module destination.
function vtk_module_autoinit()
Linking to autoinit-using modules.
function vtk_module_add_module(name)
Create a module library.
@ component
Definition vtkX3D.h:181
@ order
Definition vtkX3D.h:446
@ location
Definition vtkX3D.h:412
@ on
Definition vtkX3D.h:445
@ function
Definition vtkX3D.h:255
@ previous
Definition vtkX3D.h:455
@ value
Definition vtkX3D.h:226
@ name
Definition vtkX3D.h:225
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 *)