vtkModuleWrapPython.cmake 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. #[==[
  2. @defgroup module-wrapping-python Module Python CMake APIs
  3. #]==]
  4. #[==[
  5. @file vtkModuleWrapPython.cmake
  6. @brief APIs for wrapping modules for Python
  7. @section Limitations
  8. Known limitations include:
  9. - Shared Python modules only really support shared builds of modules. VTK
  10. does not provide mangling facilities for itself, so statically linking VTK
  11. into its Python modules precludes using VTK's C++ interface anywhere else
  12. within the Python environment.
  13. - Only supports CPython. Other implementations are not supported by the
  14. `VTK::WrapPython` executable.
  15. - Links directly to a Python library. See the `VTK::Python` module for more
  16. details.
  17. #]==]
  18. #[==[
  19. @ingroup module-wrapping-python
  20. @brief Determine Python module destination
  21. Some projects may need to know where Python expects its modules to be placed in
  22. the install tree (assuming a shared prefix). This function computes the default
  23. and sets the passed variable to the value in the calling scope.
  24. ~~~
  25. vtk_module_python_default_destination(<var>
  26. [MAJOR_VERSION <major>])
  27. ~~~
  28. By default, the destination is `${CMAKE_INSTALL_BINDIR}/Lib/site-packages` on
  29. Windows and `${CMAKE_INSTALL_LIBDIR}/python<VERSION>/site-packages` otherwise.
  30. `<MAJOR_VERSION>` must be one of `2` or `3`. If not specified, it defaults to
  31. the value of `${VTK_PYTHON_VERSION}`.
  32. #]==]
  33. function (vtk_module_python_default_destination var)
  34. cmake_parse_arguments(_vtk_module_python
  35. ""
  36. "MAJOR_VERSION"
  37. ""
  38. ${ARGN})
  39. if (_vtk_module_python_UNPARSED_ARGUMENTS)
  40. message(FATAL_ERROR
  41. "Unparsed arguments for vtk_module_python_default_destination: "
  42. "${_vtk_module_python_UNPARSED_ARGUMENTS}")
  43. endif ()
  44. if (NOT _vtk_module_python_MAJOR_VERSION)
  45. if (NOT DEFINED VTK_PYTHON_VERSION)
  46. message(FATAL_ERROR
  47. "A major version of Python must be specified (or `VTK_PYTHON_VERSION` "
  48. "be set).")
  49. endif ()
  50. set(_vtk_module_python_MAJOR_VERSION "${VTK_PYTHON_VERSION}")
  51. endif ()
  52. if (NOT _vtk_module_python_MAJOR_VERSION STREQUAL "2" AND
  53. NOT _vtk_module_python_MAJOR_VERSION STREQUAL "3")
  54. message(FATAL_ERROR
  55. "Only Python2 and Python3 are supported right now.")
  56. endif ()
  57. if (WIN32 AND NOT CYGWIN)
  58. set(destination "${CMAKE_INSTALL_BINDIR}/Lib/site-packages")
  59. else ()
  60. if (NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR" OR
  61. NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR")
  62. find_package("Python${_vtk_module_python_MAJOR_VERSION}" QUIET COMPONENTS Development.Module)
  63. endif ()
  64. if (Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR AND Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR)
  65. set(_vtk_python_version_suffix "${Python${VTK_PYTHON_VERSION}_VERSION_MAJOR}.${Python${VTK_PYTHON_VERSION}_VERSION_MINOR}")
  66. else ()
  67. message(WARNING
  68. "The version of Python is unknown; not using a versioned directory "
  69. "for Python modules.")
  70. set(_vtk_python_version_suffix)
  71. endif ()
  72. set(destination "${CMAKE_INSTALL_LIBDIR}/python${_vtk_python_version_suffix}/site-packages")
  73. endif ()
  74. set("${var}" "${destination}" PARENT_SCOPE)
  75. endfunction ()
  76. #[==[
  77. @ingroup module-impl
  78. @brief Generate sources for using a module's classes from Python
  79. This function generates the wrapped sources for a module. It places the list of
  80. generated source files and classes in variables named in the second and third
  81. arguments, respectively.
  82. ~~~
  83. _vtk_module_wrap_python_sources(<module> <sources> <classes>)
  84. ~~~
  85. #]==]
  86. function (_vtk_module_wrap_python_sources module sources classes)
  87. _vtk_module_get_module_property("${module}"
  88. PROPERTY "exclude_wrap"
  89. VARIABLE _vtk_python_exclude_wrap)
  90. if (_vtk_python_exclude_wrap)
  91. return ()
  92. endif ()
  93. file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python")
  94. set(_vtk_python_args_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python/${_vtk_python_library_name}-python.$<CONFIGURATION>.args")
  95. set(_vtk_python_hierarchy_depends "${module}")
  96. _vtk_module_get_module_property("${module}"
  97. PROPERTY "private_depends"
  98. VARIABLE _vtk_python_private_depends)
  99. list(APPEND _vtk_python_hierarchy_depends ${_vtk_python_private_depends})
  100. set(_vtk_python_command_depends)
  101. foreach (_vtk_python_hierarchy_depend IN LISTS _vtk_python_hierarchy_depends)
  102. _vtk_module_get_module_property("${_vtk_python_hierarchy_depend}"
  103. PROPERTY "hierarchy"
  104. VARIABLE _vtk_python_hierarchy_file)
  105. if (_vtk_python_hierarchy_file)
  106. list(APPEND _vtk_python_hierarchy_files "${_vtk_python_hierarchy_file}")
  107. get_property(_vtk_python_is_imported
  108. TARGET "${_vtk_python_hierarchy_depend}"
  109. PROPERTY "IMPORTED")
  110. if (_vtk_python_is_imported OR CMAKE_GENERATOR MATCHES "Ninja")
  111. list(APPEND _vtk_python_command_depends "${_vtk_python_hierarchy_file}")
  112. else ()
  113. _vtk_module_get_module_property("${_vtk_python_hierarchy_depend}"
  114. PROPERTY "library_name"
  115. VARIABLE _vtk_python_hierarchy_library_name)
  116. if (TARGET "${_vtk_python_hierarchy_library_name}-hierarchy")
  117. list(APPEND _vtk_python_command_depends "${_vtk_python_hierarchy_library_name}-hierarchy")
  118. else ()
  119. message(FATAL_ERROR
  120. "The ${_vtk_python_hierarchy_depend} hierarchy file is attached to a non-imported target "
  121. "and a hierarchy target (${_vtk_python_hierarchy_library_name}-hierarchy) is "
  122. "missing.")
  123. endif ()
  124. endif ()
  125. endif ()
  126. endforeach ()
  127. set(_vtk_python_genex_compile_definitions
  128. "$<TARGET_PROPERTY:${_vtk_python_target_name},COMPILE_DEFINITIONS>")
  129. set(_vtk_python_genex_include_directories
  130. "$<TARGET_PROPERTY:${_vtk_python_target_name},INCLUDE_DIRECTORIES>")
  131. file(GENERATE
  132. OUTPUT "${_vtk_python_args_file}"
  133. CONTENT "$<$<BOOL:${_vtk_python_genex_compile_definitions}>:\n-D\'$<JOIN:${_vtk_python_genex_compile_definitions},\'\n-D\'>\'>\n
  134. $<$<BOOL:${_vtk_python_genex_include_directories}>:\n-I\'$<JOIN:${_vtk_python_genex_include_directories},\'\n-I\'>\'>\n
  135. $<$<BOOL:${_vtk_python_hierarchy_files}>:\n--types \'$<JOIN:${_vtk_python_hierarchy_files},\'\n--types \'>\'>\n")
  136. set(_vtk_python_sources)
  137. # Get the list of public headers from the module.
  138. _vtk_module_get_module_property("${module}"
  139. PROPERTY "headers"
  140. VARIABLE _vtk_python_headers)
  141. set(_vtk_python_classes)
  142. foreach (_vtk_python_header IN LISTS _vtk_python_headers)
  143. # Assume the class name matches the basename of the header. This is VTK
  144. # convention.
  145. get_filename_component(_vtk_python_basename "${_vtk_python_header}" NAME_WE)
  146. list(APPEND _vtk_python_classes
  147. "${_vtk_python_basename}")
  148. set(_vtk_python_source_output
  149. "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_library_name}Python/${_vtk_python_basename}Python.cxx")
  150. list(APPEND _vtk_python_sources
  151. "${_vtk_python_source_output}")
  152. set(_vtk_python_wrap_target "VTK::WrapPython")
  153. set(_vtk_python_macros_args)
  154. if (TARGET VTKCompileTools::WrapPython)
  155. set(_vtk_python_wrap_target "VTKCompileTools::WrapPython")
  156. if (TARGET VTKCompileTools_macros)
  157. list(APPEND _vtk_python_command_depends
  158. "VTKCompileTools_macros")
  159. list(APPEND _vtk_python_macros_args
  160. -undef
  161. -imacros "${_VTKCompileTools_macros_file}")
  162. endif ()
  163. endif ()
  164. add_custom_command(
  165. OUTPUT "${_vtk_python_source_output}"
  166. COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR}
  167. "$<TARGET_FILE:${_vtk_python_wrap_target}>"
  168. "@${_vtk_python_args_file}"
  169. -o "${_vtk_python_source_output}"
  170. "${_vtk_python_header}"
  171. ${_vtk_python_macros_args}
  172. IMPLICIT_DEPENDS
  173. CXX "${_vtk_python_header}"
  174. COMMENT "Generating Python wrapper sources for ${_vtk_python_basename}"
  175. DEPENDS
  176. "${_vtk_python_header}"
  177. "${_vtk_python_args_file}"
  178. "$<TARGET_FILE:${_vtk_python_wrap_target}>"
  179. ${_vtk_python_command_depends})
  180. endforeach ()
  181. set("${sources}"
  182. "${_vtk_python_sources}"
  183. PARENT_SCOPE)
  184. set("${classes}"
  185. "${_vtk_python_classes}"
  186. PARENT_SCOPE)
  187. endfunction ()
  188. #[==[
  189. @ingroup module-impl
  190. @brief Generate a CPython library for a set of modules
  191. A Python module library may consist of the Python wrappings of multiple
  192. modules. This is useful for kit-based builds where the modules part of the same
  193. kit belong to the same Python module as well.
  194. ~~~
  195. _vtk_module_wrap_python_library(<name> <module>...)
  196. ~~~
  197. The first argument is the name of the Python module. The remaining arguments
  198. are modules to include in the Python module.
  199. The remaining information it uses is assumed to be provided by the
  200. @ref vtk_module_wrap_python function.
  201. #]==]
  202. function (_vtk_module_wrap_python_library name)
  203. set(_vtk_python_library_sources)
  204. set(_vtk_python_library_classes)
  205. foreach (_vtk_python_module IN LISTS ARGN)
  206. _vtk_module_get_module_property("${_vtk_python_module}"
  207. PROPERTY "exclude_wrap"
  208. VARIABLE _vtk_python_exclude_wrap)
  209. if (_vtk_python_exclude_wrap)
  210. continue ()
  211. endif ()
  212. _vtk_module_real_target(_vtk_python_target_name "${_vtk_python_module}")
  213. _vtk_module_get_module_property("${_vtk_python_module}"
  214. PROPERTY "library_name"
  215. VARIABLE _vtk_python_library_name)
  216. # Wrap the module independently of the other VTK modules in the Python
  217. # module.
  218. _vtk_module_wrap_python_sources("${_vtk_python_module}" _vtk_python_sources _vtk_python_classes)
  219. list(APPEND _vtk_python_library_sources
  220. ${_vtk_python_sources})
  221. list(APPEND _vtk_python_library_classes
  222. ${_vtk_python_classes})
  223. # Make sure the module doesn't already have an associated Python package.
  224. vtk_module_get_property("${_vtk_python_module}"
  225. PROPERTY "INTERFACE_vtk_module_python_package"
  226. VARIABLE _vtk_python_current_python_package)
  227. if (DEFINED _vtk_python_current_python_package)
  228. message(FATAL_ERROR
  229. "It appears as though the ${_vtk_python_module} has already been "
  230. "wrapped in Python in the ${_vtk_python_current_python_package} "
  231. "package.")
  232. endif ()
  233. vtk_module_set_property("${_vtk_python_module}"
  234. PROPERTY "INTERFACE_vtk_module_python_package"
  235. VALUE "${_vtk_python_PYTHON_PACKAGE}")
  236. if (_vtk_python_INSTALL_HEADERS)
  237. _vtk_module_export_properties(
  238. BUILD_FILE "${_vtk_python_properties_build_file}"
  239. INSTALL_FILE "${_vtk_python_properties_install_file}"
  240. MODULE "${_vtk_python_module}"
  241. PROPERTIES
  242. # Export the wrapping hints file.
  243. INTERFACE_vtk_module_python_package)
  244. endif ()
  245. endforeach ()
  246. # The foreach needs to be split so that dependencies are guaranteed to have
  247. # the INTERFACE_vtk_module_python_package property set.
  248. foreach (_vtk_python_module IN LISTS ARGN)
  249. _vtk_module_get_module_property("${_vtk_python_module}"
  250. PROPERTY "exclude_wrap"
  251. VARIABLE _vtk_python_exclude_wrap)
  252. if (_vtk_python_exclude_wrap)
  253. continue ()
  254. endif ()
  255. _vtk_module_get_module_property("${_vtk_python_module}"
  256. PROPERTY "library_name"
  257. VARIABLE _vtk_python_library_name)
  258. _vtk_module_get_module_property("${_vtk_python_module}"
  259. PROPERTY "depends"
  260. VARIABLE _vtk_python_module_depends)
  261. set(_vtk_python_module_load_depends)
  262. foreach (_vtk_python_module_depend IN LISTS _vtk_python_module_depends)
  263. _vtk_module_get_module_property("${_vtk_python_module_depend}"
  264. PROPERTY "exclude_wrap"
  265. VARIABLE _vtk_python_module_depend_exclude_wrap)
  266. if (_vtk_python_module_depend_exclude_wrap)
  267. continue ()
  268. endif ()
  269. _vtk_module_get_module_property("${_vtk_python_module_depend}"
  270. PROPERTY "python_package"
  271. VARIABLE _vtk_python_depend_module_package)
  272. _vtk_module_get_module_property("${_vtk_python_module_depend}"
  273. PROPERTY "library_name"
  274. VARIABLE _vtk_python_depend_library_name)
  275. # XXX(kits): This doesn't work for kits.
  276. list(APPEND _vtk_python_module_load_depends
  277. "${_vtk_python_depend_module_package}.${_vtk_python_depend_library_name}")
  278. endforeach ()
  279. if (_vtk_python_BUILD_STATIC)
  280. # If static, we use .py modules that grab the contents from the baked-in modules.
  281. set(_vtk_python_module_file
  282. "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}/${_vtk_python_library_name}.py")
  283. set(_vtk_python_module_contents
  284. "from ${_vtk_python_import_prefix}${_vtk_python_library_name} import *\n")
  285. file(GENERATE
  286. OUTPUT "${_vtk_python_module_file}"
  287. CONTENT "${_vtk_python_module_contents}")
  288. # Set `python_modules` to provide the list of python files that go along with
  289. # this module
  290. _vtk_module_set_module_property("${_vtk_python_module}" APPEND
  291. PROPERTY "python_modules"
  292. VALUE "${_vtk_python_module_file}")
  293. endif ()
  294. endforeach ()
  295. if (NOT _vtk_python_library_sources)
  296. return ()
  297. endif ()
  298. set(_vtk_python_init_data_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}Python/${name}-init.data")
  299. file(GENERATE
  300. OUTPUT "${_vtk_python_init_data_file}"
  301. CONTENT "${_vtk_python_library_name}\n$<JOIN:${_vtk_python_classes},\n>\nDEPENDS\n$<JOIN:${_vtk_python_module_load_depends},\n>\n")
  302. set(_vtk_python_init_output
  303. "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}Python/${name}Init.cxx")
  304. set(_vtk_python_init_impl_output
  305. "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}Python/${name}InitImpl.cxx")
  306. list(APPEND _vtk_python_library_sources
  307. "${_vtk_python_init_output}"
  308. "${_vtk_python_init_impl_output}")
  309. set(_vtk_python_wrap_target "VTK::WrapPythonInit")
  310. if (TARGET VTKCompileTools::WrapPythonInit)
  311. set(_vtk_python_wrap_target "VTKCompileTools::WrapPythonInit")
  312. endif ()
  313. if(_vtk_python_BUILD_STATIC)
  314. set(additonal_options "${_vtk_python_import_prefix}")
  315. endif()
  316. add_custom_command(
  317. OUTPUT "${_vtk_python_init_output}"
  318. "${_vtk_python_init_impl_output}"
  319. COMMAND "${_vtk_python_wrap_target}"
  320. "${_vtk_python_init_data_file}"
  321. "${_vtk_python_init_output}"
  322. "${_vtk_python_init_impl_output}"
  323. "${additonal_options}"
  324. COMMENT "Generating the Python module initialization sources for ${name}"
  325. DEPENDS
  326. "${_vtk_python_init_data_file}"
  327. "$<TARGET_FILE:${_vtk_python_wrap_target}>")
  328. if (_vtk_python_BUILD_STATIC)
  329. set(_vtk_python_module_header_file
  330. "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}/static_python/${name}.h")
  331. set(_vtk_python_module_header_content
  332. "#ifndef ${name}_h
  333. #define ${name}_h
  334. #include <vtkPython.h>
  335. #ifdef __cplusplus
  336. extern \"C\" {
  337. #endif
  338. #if PY_VERSION_HEX < 0x03000000
  339. extern void init${_vtk_python_library_name}();
  340. #else
  341. extern PyObject* PyInit_${_vtk_python_library_name}();
  342. #endif
  343. #ifdef __cplusplus
  344. }
  345. #endif
  346. #endif
  347. ")
  348. file(GENERATE
  349. OUTPUT "${_vtk_python_module_header_file}"
  350. CONTENT "${_vtk_python_module_header_content}")
  351. # XXX(cmake): Why is this necessary? One would expect that `file(GENERATE)`
  352. # would do this automatically.
  353. set_property(SOURCE "${_vtk_python_module_header_file}"
  354. PROPERTY
  355. GENERATED 1)
  356. add_library("${name}" STATIC
  357. ${_vtk_python_library_sources}
  358. "${_vtk_python_module_header_file}")
  359. target_include_directories("${name}"
  360. INTERFACE
  361. "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}/static_python>")
  362. target_link_libraries("${name}"
  363. PUBLIC
  364. VTK::Python)
  365. set_property(TARGET "${name}"
  366. PROPERTY
  367. LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_python_STATIC_MODULE_DESTINATION}")
  368. else ()
  369. add_library("${name}" MODULE
  370. ${_vtk_python_library_sources})
  371. if (WIN32 AND NOT CYGWIN)
  372. # XXX(python-debug): This is disabled out because there's no reliable way
  373. # to tell whether we're using a debug build of Python or not. Since using
  374. # a debug Python build is so rare, just assume we're always using a
  375. # non-debug build of Python itself.
  376. #
  377. # The proper fix is to dig around and ask the backing `PythonN::Python`
  378. # target used by `VTK::Python` for its properties to find out, per
  379. # configuration, whether it is a debug build. If it is, add the postfix
  380. # (regardless of VTK's build type). Otherwise, no postfix.
  381. if (FALSE)
  382. set_property(TARGET "${name}"
  383. APPEND_STRING
  384. PROPERTY
  385. DEBUG_POSTFIX "_d")
  386. endif ()
  387. set_property(TARGET "${name}"
  388. PROPERTY
  389. SUFFIX ".pyd")
  390. endif ()
  391. set_property(TARGET "${name}"
  392. PROPERTY
  393. LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}")
  394. get_property(_vtk_python_is_multi_config GLOBAL
  395. PROPERTY GENERATOR_IS_MULTI_CONFIG)
  396. if (_vtk_python_is_multi_config)
  397. # XXX(MultiNinja): This isn't going to work in general since MultiNinja
  398. # will error about overlapping output paths.
  399. foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
  400. string(TOUPPER "${_vtk_python_config}" _vtk_python_config_upper)
  401. set_property(TARGET "${name}"
  402. PROPERTY
  403. "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}")
  404. endforeach ()
  405. endif ()
  406. set_target_properties("${name}"
  407. PROPERTIES
  408. PREFIX ""
  409. OUTPUT_NAME "${_vtk_python_library_name}"
  410. ARCHIVE_OUTPUT_NAME "${name}")
  411. endif ()
  412. vtk_module_autoinit(
  413. MODULES ${ARGN}
  414. TARGETS "${name}")
  415. # The wrapper code will expand PYTHON_PACKAGE as needed
  416. target_compile_definitions("${name}"
  417. PRIVATE
  418. "-DPYTHON_PACKAGE=\"${_vtk_python_PYTHON_PACKAGE}\"")
  419. target_link_libraries("${name}"
  420. PRIVATE
  421. ${ARGN}
  422. VTK::WrappingPythonCore
  423. VTK::Python)
  424. set(_vtk_python_export)
  425. if (_vtk_python_INSTALL_EXPORT)
  426. set(_vtk_python_export
  427. EXPORT "${_vtk_python_INSTALL_EXPORT}")
  428. endif ()
  429. install(
  430. TARGETS "${name}"
  431. ${_vtk_python_export}
  432. COMPONENT "${_vtk_python_COMPONENT}"
  433. RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
  434. LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
  435. ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}")
  436. endfunction ()
  437. #[==[
  438. @ingroup module-wrapping-python
  439. @brief Wrap a set of modules for use in Python
  440. ~~~
  441. vtk_module_wrap_python(
  442. MODULES <module>...
  443. [TARGET <target>]
  444. [WRAPPED_MODULES <varname>]
  445. [BUILD_STATIC <ON|OFF>]
  446. [INSTALL_HEADERS <ON|OFF>]
  447. [DEPENDS <target>...]
  448. [MODULE_DESTINATION <destination>]
  449. [STATIC_MODULE_DESTINATION <destination>]
  450. [CMAKE_DESTINATION <destination>]
  451. [LIBRARY_DESTINATION <destination>]
  452. [PYTHON_PACKAGE <package>]
  453. [SOABI <soabi>]
  454. [INSTALL_EXPORT <export>]
  455. [COMPONENT <component>])
  456. ~~~
  457. * `MODULES`: (Required) The list of modules to wrap.
  458. * `TARGET`: (Recommended) The target to create which represents all wrapped
  459. Python modules. This is mostly useful when supporting static Python modules
  460. in order to add the generated modules to the built-in table.
  461. * `WRAPPED_MODULES`: (Recommended) Not all modules are wrappable. This
  462. variable will be set to contain the list of modules which were wrapped.
  463. These modules will have a `INTERFACE_vtk_module_python_package` property
  464. set on them which is the name that should be given to `import` statements
  465. in Python code.
  466. * `BUILD_STATIC`: Defaults to `${BUILD_SHARED_LIBS}`. Note that shared
  467. modules with a static build is not completely supported. For static Python
  468. module builds, a header named `<TARGET>.h` will be available with a
  469. function `void <TARGET>_load()` which will add all Python modules created
  470. by this call to the imported module table. For shared Python module builds,
  471. the same function is provided, but it is a no-op.
  472. * `INSTALL_HEADERS` (Defaults to `ON`): If unset, CMake properties will not
  473. be installed.
  474. * `DEPENDS`: This is list of other Python modules targets i.e. targets
  475. generated from previous calls to `vtk_module_wrap_python` that this new
  476. target depends on. This is used when `BUILD_STATIC` is true to ensure that
  477. the `void <TARGET>_load()` is correctly called for each of the dependencies.
  478. * `MODULE_DESTINATION`: Modules will be placed in this location in the
  479. build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
  480. currently does not. See `vtk_module_python_default_destination` for the
  481. default value.
  482. * `STATIC_MODULE_DESTINATION`: Defaults to `${CMAKE_INSTALL_LIBDIR}`. This
  483. default may change in the future since the best location for these files is
  484. not yet known. Static libraries containing Python code will be installed to
  485. the install tree under this path.
  486. * `CMAKE_DESTINATION`: (Required if `INSTALL_HEADERS` is `ON`) Where to
  487. install Python-related module property CMake files.
  488. * `LIBRARY_DESTINATION` (Recommended): If provided, dynamic loader
  489. information will be added to modules for loading dependent libraries.
  490. * `PYTHON_PACKAGE`: (Recommended) All generated modules will be added to this
  491. Python package. The format is in Python syntax (e.g.,
  492. `package.subpackage`).
  493. * `SOABI`: (Required for wheel support): If given, generate libraries with
  494. the SOABI tag in the module filename.
  495. * `INSTALL_EXPORT`: If provided, static installs will add the installed
  496. libraries to the provided export set.
  497. * `COMPONENT`: Defaults to `python`. All install rules created by this
  498. function will use this installation component.
  499. #]==]
  500. function (vtk_module_wrap_python)
  501. cmake_parse_arguments(_vtk_python
  502. ""
  503. "MODULE_DESTINATION;STATIC_MODULE_DESTINATION;LIBRARY_DESTINATION;PYTHON_PACKAGE;BUILD_STATIC;INSTALL_HEADERS;INSTALL_EXPORT;TARGET;COMPONENT;WRAPPED_MODULES;CMAKE_DESTINATION;DEPENDS;SOABI"
  504. "MODULES"
  505. ${ARGN})
  506. if (_vtk_python_UNPARSED_ARGUMENTS)
  507. message(FATAL_ERROR
  508. "Unparsed arguments for vtk_module_wrap_python: "
  509. "${_vtk_python_UNPARSED_ARGUMENTS}")
  510. endif ()
  511. if (NOT _vtk_python_MODULES)
  512. message(WARNING
  513. "No modules were requested for Python wrapping.")
  514. return ()
  515. endif ()
  516. _vtk_module_split_module_name("${_vtk_python_TARGET}" _vtk_python)
  517. set(_vtk_python_depends)
  518. foreach (_vtk_python_depend IN LISTS _vtk_python_DEPENDS)
  519. _vtk_module_split_module_name("${_vtk_python_depend}" _vtk_python_depends)
  520. list(APPEND _vtk_python_depends
  521. "${_vtk_python_depends_TARGET_NAME}")
  522. endforeach ()
  523. if (NOT DEFINED _vtk_python_MODULE_DESTINATION)
  524. vtk_module_python_default_destination(_vtk_python_MODULE_DESTINATION)
  525. endif ()
  526. if (NOT DEFINED _vtk_python_INSTALL_HEADERS)
  527. set(_vtk_python_INSTALL_HEADERS ON)
  528. endif ()
  529. if (_vtk_python_SOABI)
  530. get_property(_vtk_python_is_multi_config GLOBAL
  531. PROPERTY GENERATOR_IS_MULTI_CONFIG)
  532. if (_vtk_python_is_multi_config)
  533. foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
  534. string(TOUPPER "${_vtk_python_config}" _vtk_python_upper_config)
  535. set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
  536. ".${_vtk_python_SOABI}")
  537. endforeach ()
  538. else ()
  539. string(TOUPPER "${CMAKE_BUILD_TYPE}" _vtk_python_upper_config)
  540. set("CMAKE_${_vtk_python_upper_config}_POSTFIX"
  541. ".${_vtk_python_SOABI}")
  542. endif ()
  543. endif ()
  544. if (_vtk_python_INSTALL_HEADERS AND NOT DEFINED _vtk_python_CMAKE_DESTINATION)
  545. message(FATAL_ERROR
  546. "No CMAKE_DESTINATION set, but headers from the Python wrapping were "
  547. "requested for install and the CMake files are required to work with "
  548. "them.")
  549. endif ()
  550. if (NOT DEFINED _vtk_python_BUILD_STATIC)
  551. if (BUILD_SHARED_LIBS)
  552. set(_vtk_python_BUILD_STATIC OFF)
  553. else ()
  554. set(_vtk_python_BUILD_STATIC ON)
  555. endif ()
  556. else ()
  557. if (NOT _vtk_python_BUILD_STATIC AND NOT BUILD_SHARED_LIBS)
  558. message(WARNING
  559. "Building shared Python modules against static VTK modules only "
  560. "supports consuming the VTK modules via their Python interfaces due "
  561. "to the lack of support for an SDK to use the same static libraries.")
  562. endif ()
  563. endif ()
  564. if (NOT DEFINED _vtk_python_STATIC_MODULE_DESTINATION)
  565. # TODO: Is this correct?
  566. set(_vtk_python_STATIC_MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}")
  567. endif ()
  568. if (NOT DEFINED _vtk_python_COMPONENT)
  569. set(_vtk_python_COMPONENT "python")
  570. endif ()
  571. if (NOT _vtk_python_PYTHON_PACKAGE)
  572. message(FATAL_ERROR
  573. "No `PYTHON_PACKAGE` was given; Python modules must be placed into a "
  574. "package.")
  575. endif ()
  576. string(REPLACE "." "/" _vtk_python_package_path "${_vtk_python_PYTHON_PACKAGE}")
  577. if(_vtk_python_BUILD_STATIC)
  578. # When doing static builds we want the statically initialized built-ins to be
  579. # used. It is unclear in the Python-C API how to construct `namespace.module`
  580. # so instead at the C++ level we import "namespace_module" during startup
  581. # and than the python modules moving those imports into the correct python
  582. # module.
  583. string(REPLACE "." "_" _vtk_python_import_prefix "${_vtk_python_PYTHON_PACKAGE}_")
  584. else()
  585. # We are building dynamic libraries therefore the prefix is simply '.'
  586. set(_vtk_python_import_prefix ".")
  587. endif()
  588. _vtk_module_check_destinations(_vtk_python_
  589. MODULE_DESTINATION
  590. STATIC_MODULE_DESTINATION
  591. CMAKE_DESTINATION
  592. LIBRARY_DESTINATION)
  593. if (_vtk_python_INSTALL_HEADERS)
  594. set(_vtk_python_properties_filename "${_vtk_python_PYTHON_PACKAGE}-vtk-python-module-properties.cmake")
  595. set(_vtk_python_properties_install_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/${_vtk_python_properties_filename}.install")
  596. set(_vtk_python_properties_build_file "${CMAKE_BINARY_DIR}/${_vtk_python_CMAKE_DESTINATION}/${_vtk_python_properties_filename}")
  597. file(WRITE "${_vtk_python_properties_build_file}")
  598. file(WRITE "${_vtk_python_properties_install_file}")
  599. endif ()
  600. if (DEFINED _vtk_python_LIBRARY_DESTINATION)
  601. # Set up rpaths
  602. set(CMAKE_BUILD_RPATH_USE_ORIGIN 1)
  603. if (UNIX)
  604. file(RELATIVE_PATH _vtk_python_relpath
  605. "/prefix/${_vtk_python_MODULE_DESTINATION}/${_vtk_python_package_path}"
  606. "/prefix/${_vtk_python_LIBRARY_DESTINATION}")
  607. if (APPLE)
  608. set(_vtk_python_origin_stem "@loader_path")
  609. else ()
  610. set(_vtk_python_origin_stem "$ORIGIN")
  611. endif()
  612. list(APPEND CMAKE_INSTALL_RPATH
  613. "${_vtk_python_origin_stem}/${_vtk_python_relpath}")
  614. endif ()
  615. endif ()
  616. set(_vtk_python_sorted_modules ${_vtk_python_MODULES})
  617. foreach (_vtk_python_module IN LISTS _vtk_python_MODULES)
  618. _vtk_module_get_module_property("${_vtk_python_module}"
  619. PROPERTY "depends"
  620. VARIABLE "_vtk_python_${_vtk_python_module}_depends")
  621. endforeach ()
  622. vtk_topological_sort(_vtk_python_sorted_modules "_vtk_python_" "_depends")
  623. set(_vtk_python_sorted_modules_filtered)
  624. foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules)
  625. if (_vtk_python_module IN_LIST _vtk_python_MODULES)
  626. list(APPEND _vtk_python_sorted_modules_filtered
  627. "${_vtk_python_module}")
  628. endif ()
  629. endforeach ()
  630. set(_vtk_python_all_modules)
  631. set(_vtk_python_all_wrapped_modules)
  632. foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
  633. _vtk_module_get_module_property("${_vtk_python_module}"
  634. PROPERTY "library_name"
  635. VARIABLE _vtk_python_library_name)
  636. _vtk_module_wrap_python_library("${_vtk_python_library_name}Python" "${_vtk_python_module}")
  637. if (TARGET "${_vtk_python_library_name}Python")
  638. list(APPEND _vtk_python_all_modules
  639. "${_vtk_python_library_name}Python")
  640. list(APPEND _vtk_python_all_wrapped_modules
  641. "${_vtk_python_module}")
  642. endif ()
  643. endforeach ()
  644. if (NOT _vtk_python_all_modules)
  645. message(FATAL_ERROR
  646. "No modules given could be wrapped.")
  647. endif ()
  648. if (_vtk_python_INSTALL_HEADERS)
  649. install(
  650. FILES "${_vtk_python_properties_install_file}"
  651. DESTINATION "${_vtk_python_CMAKE_DESTINATION}"
  652. RENAME "${_vtk_python_properties_filename}"
  653. COMPONENT "development")
  654. endif ()
  655. if (DEFINED _vtk_python_WRAPPED_MODULES)
  656. set("${_vtk_python_WRAPPED_MODULES}"
  657. "${_vtk_python_all_wrapped_modules}"
  658. PARENT_SCOPE)
  659. endif ()
  660. if (_vtk_python_TARGET)
  661. add_library("${_vtk_python_TARGET_NAME}" INTERFACE)
  662. target_include_directories("${_vtk_python_TARGET_NAME}"
  663. INTERFACE
  664. "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python>")
  665. target_link_libraries("${_vtk_python_TARGET_NAME}"
  666. INTERFACE
  667. ${_vtk_python_DEPENDS})
  668. if (NOT _vtk_python_TARGET STREQUAL _vtk_python_TARGET_NAME)
  669. add_library("${_vtk_python_TARGET}" ALIAS
  670. "${_vtk_python_TARGET_NAME}")
  671. endif ()
  672. if (_vtk_python_INSTALL_EXPORT)
  673. install(
  674. TARGETS "${_vtk_python_TARGET_NAME}"
  675. EXPORT "${_vtk_python_INSTALL_EXPORT}"
  676. COMPONENT "development")
  677. endif ()
  678. set(_vtk_python_all_modules_include_file
  679. "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_TARGET_NAME}.h")
  680. set(_vtk_python_all_modules_include_content
  681. "#ifndef ${_vtk_python_TARGET_NAME}_h\n#define ${_vtk_python_TARGET_NAME}_h\n")
  682. if (_vtk_python_BUILD_STATIC)
  683. foreach (_vtk_python_module IN LISTS _vtk_python_all_modules)
  684. string(APPEND _vtk_python_all_modules_include_content
  685. "#include \"${_vtk_python_module}.h\"\n")
  686. endforeach ()
  687. endif ()
  688. foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
  689. string(APPEND _vtk_python_all_modules_include_content
  690. "#include \"${_vtk_python_depend}.h\"\n")
  691. endforeach ()
  692. string(APPEND _vtk_python_all_modules_include_content
  693. "#if PY_VERSION_HEX < 0x03000000
  694. #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, init ## module)
  695. #define PY_IMPORT(module) init ## module();
  696. #else
  697. #define PY_APPEND_INIT(module) PyImport_AppendInittab(\"${_vtk_python_import_prefix}\" #module, PyInit_ ## module)
  698. #define PY_IMPORT(module) { \\
  699. PyObject* var_ ## module = PyInit_ ## module(); \\
  700. PyDict_SetItemString(PyImport_GetModuleDict(), \"${_vtk_python_import_prefix}\" #module,var_ ## module); \\
  701. Py_DECREF(var_ ## module); }
  702. #endif
  703. #define PY_APPEND_INIT_OR_IMPORT(module, do_import) \\
  704. if (do_import) { PY_IMPORT(module); } else { PY_APPEND_INIT(module); }
  705. static void ${_vtk_python_TARGET_NAME}_load() {\n")
  706. foreach (_vtk_python_depend IN LISTS _vtk_python_depends)
  707. string(APPEND _vtk_python_all_modules_include_content
  708. " ${_vtk_python_depend}_load();\n")
  709. endforeach ()
  710. if (_vtk_python_BUILD_STATIC)
  711. string(APPEND _vtk_python_all_modules_include_content
  712. " int do_import = Py_IsInitialized();\n")
  713. foreach (_vtk_python_module IN LISTS _vtk_python_sorted_modules_filtered)
  714. _vtk_module_get_module_property("${_vtk_python_module}"
  715. PROPERTY "library_name"
  716. VARIABLE _vtk_python_library_name)
  717. if (TARGET "${_vtk_python_library_name}Python")
  718. string(APPEND _vtk_python_all_modules_include_content
  719. " PY_APPEND_INIT_OR_IMPORT(${_vtk_python_library_name}, do_import);\n")
  720. endif ()
  721. endforeach ()
  722. endif ()
  723. string(APPEND _vtk_python_all_modules_include_content
  724. "}\n#undef PY_APPEND_INIT\n#undef PY_IMPORT\n#undef PY_APPEND_INIT_OR_IMPORT\n#endif\n")
  725. # TODO: Install this header.
  726. file(GENERATE
  727. OUTPUT "${_vtk_python_all_modules_include_file}"
  728. CONTENT "${_vtk_python_all_modules_include_content}")
  729. if (_vtk_python_BUILD_STATIC)
  730. # TODO: Install these targets.
  731. target_link_libraries("${_vtk_python_TARGET_NAME}"
  732. INTERFACE
  733. ${_vtk_python_all_modules})
  734. endif ()
  735. if (_vtk_python_BUILD_STATIC)
  736. # Next, we generate a Python module that can be imported to import any
  737. # static artifacts e.g. all wrapping Python modules in static builds,
  738. # (eventually, frozen modules etc.)
  739. string(REPLACE "." "_" _vtk_python_static_importer_name "_${_vtk_python_PYTHON_PACKAGE}_static")
  740. set(_vtk_python_static_importer_file
  741. "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_python_TARGET_NAME}/static_python/${_vtk_python_static_importer_name}.c")
  742. set(_vtk_python_static_importer_content "// generated file, do not edit!
  743. #include <vtkPython.h>
  744. #include \"${_vtk_python_TARGET_NAME}.h\"
  745. static PyMethodDef Py${_vtk_python_static_importer_name}_Methods[] = {
  746. {NULL, NULL, 0, NULL}};
  747. #if PY_VERSION_HEX >= 0x03000000
  748. static PyModuleDef ${_vtk_python_static_importer_name}Module = {
  749. PyModuleDef_HEAD_INIT,
  750. \"${_vtk_python_static_importer_name}\", // m_name
  751. \"module to import static components for ${_vtk_python_TARGET_NAME}\", // m_doc
  752. 0, // m_size
  753. Py${_vtk_python_static_importer_name}_Methods, // m_methods
  754. NULL, // m_reload
  755. NULL, // m_traverse
  756. NULL, // m_clear
  757. NULL // m_free
  758. };
  759. #endif
  760. #if PY_VERSION_HEX >= 0x03000000
  761. PyMODINIT_FUNC PyInit_${_vtk_python_static_importer_name}(void)
  762. #else
  763. PyMODINIT_FUNC init${_vtk_python_static_importer_name}(void)
  764. #endif
  765. {
  766. // since this gets called after `Py_Initialize`, this will import the static
  767. // modules and not just update the init table.
  768. ${_vtk_python_TARGET_NAME}_load();
  769. #if PY_VERSION_HEX >= 0x03000000
  770. return PyModule_Create(&${_vtk_python_static_importer_name}Module);
  771. #else
  772. Py_InitModule(\"${_vtk_python_static_importer_name}\", Py${_vtk_python_static_importer_name}_Methods);
  773. #endif
  774. }\n")
  775. # TODO: Install this header.
  776. file(GENERATE
  777. OUTPUT "${_vtk_python_static_importer_file}"
  778. CONTENT "${_vtk_python_static_importer_content}")
  779. add_library("${_vtk_python_static_importer_name}" MODULE
  780. ${_vtk_python_static_importer_file})
  781. if (WIN32 AND NOT CYGWIN)
  782. set_property(TARGET "${_vtk_python_static_importer_name}"
  783. PROPERTY
  784. SUFFIX ".pyd")
  785. endif()
  786. set_property(TARGET "${_vtk_python_static_importer_name}"
  787. PROPERTY
  788. LIBRARY_OUTPUT_DIRECTORY "${_vtk_python_MODULE_DESTINATION}")
  789. get_property(_vtk_python_is_multi_config GLOBAL
  790. PROPERTY GENERATOR_IS_MULTI_CONFIG)
  791. if (_vtk_python_is_multi_config)
  792. # XXX(MultiNinja): This isn't going to work in general since MultiNinja
  793. # will error about overlapping output paths.
  794. foreach (_vtk_python_config IN LISTS CMAKE_CONFIGURATION_TYPES)
  795. string(TOUPPER "${_vtk_python_config}" _vtk_python_config_upper)
  796. set_property(TARGET "${_vtk_python_static_importer_name}"
  797. PROPERTY
  798. "LIBRARY_OUTPUT_DIRECTORY_${_vtk_python_config_upper}" "${CMAKE_BINARY_DIR}/${_vtk_python_MODULE_DESTINATION}")
  799. endforeach ()
  800. endif ()
  801. set_property(TARGET "${_vtk_python_static_importer_name}"
  802. PROPERTY
  803. PREFIX "")
  804. target_link_libraries("${_vtk_python_static_importer_name}"
  805. PRIVATE
  806. ${_vtk_python_TARGET_NAME}
  807. VTK::WrappingPythonCore
  808. VTK::Python)
  809. install(
  810. TARGETS "${_vtk_python_static_importer_name}"
  811. COMPONENT "${_vtk_python_COMPONENT}"
  812. RUNTIME DESTINATION "${_vtk_python_MODULE_DESTINATION}"
  813. LIBRARY DESTINATION "${_vtk_python_MODULE_DESTINATION}"
  814. ARCHIVE DESTINATION "${_vtk_python_STATIC_MODULE_DESTINATION}")
  815. endif () # if (_vtk_python_BUILD_STATIC)
  816. endif ()
  817. endfunction ()
  818. #[==[
  819. @ingroup module-wrapping-python
  820. @brief Install Python packages with a module
  821. Some modules may have associated Python code. This function should be used to
  822. install them.
  823. ~~~
  824. vtk_module_add_python_package(<module>
  825. PACKAGE <package>
  826. FILES <files>...
  827. [MODULE_DESTINATION <destination>]
  828. [COMPONENT <component>])
  829. ~~~
  830. The `<module>` argument must match the associated VTK module that the package
  831. is with. Each package is independent and should be installed separately. That
  832. is, `package` and `package.subpackage` should each get their own call to this
  833. function.
  834. * `PACKAGE`: (Required) The package installed by this call. Currently,
  835. subpackages must have their own call to this function.
  836. * `FILES`: (Required) File paths should be relative to the source directory
  837. of the calling `CMakeLists.txt`. Upward paths are not supported (nor are
  838. checked for). Absolute paths are assumed to be in the build tree and their
  839. relative path is computed relative to the current binary directory.
  840. * `MODULE_DESTINATION`: Modules will be placed in this location in the
  841. build tree. The install tree should remove `$<CONFIGURATION>` bits, but it
  842. currently does not. See `vtk_module_python_default_destination` for the
  843. default value.
  844. * `COMPONENT`: Defaults to `python`. All install rules created by this
  845. function will use this installation component.
  846. A `<module>-<package>` target is created which ensures that all Python modules
  847. have been copied to the correct location in the build tree.
  848. @todo Support a tree of modules with a single call.
  849. @todo Support freezing the Python package. This should create a header and the
  850. associated target should provide an interface for including this header. The
  851. target should then be exported and the header installed properly.
  852. #]==]
  853. function (vtk_module_add_python_package name)
  854. if (NOT name STREQUAL _vtk_build_module)
  855. message(FATAL_ERROR
  856. "Python modules must match their module names.")
  857. endif ()
  858. cmake_parse_arguments(_vtk_add_python_package
  859. ""
  860. "PACKAGE;MODULE_DESTINATION;COMPONENT"
  861. "FILES"
  862. ${ARGN})
  863. if (_vtk_add_python_package_UNPARSED_ARGUMENTS)
  864. message(FATAL_ERROR
  865. "Unparsed arguments for vtk_module_add_python_package: "
  866. "${_vtk_add_python_package_UNPARSED_ARGUMENTS}")
  867. endif ()
  868. if (NOT _vtk_add_python_package_PACKAGE)
  869. message(FATAL_ERROR
  870. "The `PACKAGE` argument is required.")
  871. endif ()
  872. string(REPLACE "." "/" _vtk_add_python_package_path "${_vtk_add_python_package_PACKAGE}")
  873. if (NOT _vtk_add_python_package_FILES)
  874. message(FATAL_ERROR
  875. "The `FILES` argument is required.")
  876. endif ()
  877. if (NOT DEFINED _vtk_add_python_package_MODULE_DESTINATION)
  878. vtk_module_python_default_destination(_vtk_add_python_package_MODULE_DESTINATION)
  879. endif ()
  880. if (NOT DEFINED _vtk_add_python_package_COMPONENT)
  881. set(_vtk_add_python_package_COMPONENT "python")
  882. endif ()
  883. set(_vtk_add_python_package_file_outputs)
  884. foreach (_vtk_add_python_package_file IN LISTS _vtk_add_python_package_FILES)
  885. if (IS_ABSOLUTE "${_vtk_add_python_package_file}")
  886. file(RELATIVE_PATH _vtk_add_python_package_name
  887. "${CMAKE_CURRENT_BINARY_DIR}"
  888. "${_vtk_add_python_package_name}")
  889. else ()
  890. set(_vtk_add_python_package_name
  891. "${_vtk_add_python_package_file}")
  892. set(_vtk_add_python_package_file
  893. "${CMAKE_CURRENT_SOURCE_DIR}/${_vtk_add_python_package_file}")
  894. endif ()
  895. set(_vtk_add_python_package_file_output
  896. "${CMAKE_BINARY_DIR}/${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_name}")
  897. add_custom_command(
  898. OUTPUT "${_vtk_add_python_package_file_output}"
  899. DEPENDS "${_vtk_add_python_package_file}"
  900. COMMAND "${CMAKE_COMMAND}" -E copy_if_different
  901. "${_vtk_add_python_package_file}"
  902. "${_vtk_add_python_package_file_output}"
  903. COMMENT "Copying ${_vtk_add_python_package_name} to the binary directory")
  904. list(APPEND _vtk_add_python_package_file_outputs
  905. "${_vtk_add_python_package_file_output}")
  906. # XXX
  907. if (BUILD_SHARED_LIBS)
  908. install(
  909. FILES "${_vtk_add_python_package_name}"
  910. DESTINATION "${_vtk_add_python_package_MODULE_DESTINATION}/${_vtk_add_python_package_path}"
  911. COMPONENT "${_vtk_add_python_package_COMPONENT}")
  912. endif()
  913. endforeach ()
  914. get_property(_vtk_add_python_package_module GLOBAL
  915. PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
  916. add_custom_target("${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}" ALL
  917. DEPENDS
  918. ${_vtk_add_python_package_file_outputs})
  919. # Set `python_modules` to provide the list of python files that go along with
  920. # this module
  921. set_property(TARGET "${_vtk_add_python_package_module}-${_vtk_add_python_package_PACKAGE}"
  922. PROPERTY
  923. "python_modules" "${_vtk_add_python_package_file_outputs}")
  924. endfunction ()
  925. #[==[
  926. @ingroup module-wrapping-python
  927. @brief Use a Python package as a module
  928. If a module is a Python package, this function should be used instead of
  929. @ref vtk_module_add_module.
  930. ~~~
  931. vtk_module_add_python_module(<name>
  932. PACKAGES <packages>...)
  933. ~~~
  934. * `PACKAGES`: (Required) The list of packages installed by this module.
  935. These must have been created by the @ref vtk_module_add_python_package
  936. function.
  937. #]==]
  938. function (vtk_module_add_python_module name)
  939. if (NOT name STREQUAL _vtk_build_module)
  940. message(FATAL_ERROR
  941. "Python modules must match their module names.")
  942. endif ()
  943. cmake_parse_arguments(_vtk_add_python_module
  944. ""
  945. ""
  946. "PACKAGES"
  947. ${ARGN})
  948. if (_vtk_add_python_module_UNPARSED_ARGUMENTS)
  949. message(FATAL_ERROR
  950. "Unparsed arguments for vtk_module_add_python_module: "
  951. "${_vtk_add_python_module_UNPARSED_ARGUMENTS}")
  952. endif ()
  953. get_property(_vtk_add_python_module_depends GLOBAL
  954. PROPERTY "_vtk_module_${_vtk_build_module}_depends")
  955. get_property(_vtk_add_python_module_target_name GLOBAL
  956. PROPERTY "_vtk_module_${_vtk_build_module}_target_name")
  957. add_library("${_vtk_add_python_module_target_name}" INTERFACE)
  958. target_link_libraries("${_vtk_add_python_module_target_name}"
  959. INTERFACE
  960. ${_vtk_add_python_module_depends})
  961. if (NOT _vtk_build_module STREQUAL _vtk_add_python_module_target_name)
  962. add_library("${_vtk_build_module}" ALIAS
  963. "${_vtk_add_python_module_target_name}")
  964. endif ()
  965. foreach (_vtk_add_python_module_package IN LISTS _vtk_add_python_module_PACKAGES)
  966. add_dependencies("${_vtk_add_python_module_target_name}"
  967. "${_vtk_build_module}-${_vtk_add_python_module_package}")
  968. # get the list of python files and add them on the module.
  969. get_property(_vtk_module_python_modules
  970. TARGET "${_vtk_add_python_module_target_name}-${_vtk_add_python_module_package}"
  971. PROPERTY "python_modules")
  972. _vtk_module_set_module_property("${_vtk_build_module}" APPEND
  973. PROPERTY "python_modules"
  974. VALUE "${_vtk_module_python_modules}")
  975. endforeach ()
  976. _vtk_module_apply_properties("${_vtk_add_python_module_target_name}")
  977. _vtk_module_install("${_vtk_add_python_module_target_name}")
  978. endfunction ()