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