1include(vtkPythonPackages)
2
3#------------------------------------------------------------------------------
4# This file extends vtkModuleMacros.cmake to add support for VTK modules that
5# are pure Python packages or modules.
6#------------------------------------------------------------------------------
7
8#------------------------------------------------------------------------------
9# Corresponds to vtk_module_library(), instead we're now adding a Python
10# package. This is designed for packages and hence do not use when dealing with
11# Python modules.
12# Typical usage is as follows:
13# vtk_module_python_package(
14#   AutobahnPython  # name of the vtk-module
15#   autobahn        # package directory i.e. the directory with __init__.py file.
16#   ...             # additional packages.
17#   [NO_INSTALL]    # if present, install rules are skipped.
18#   [CAN_USE_SYSTEM]    # if present, user will be provided with an option to use
19#                       # system package.
20#   [RELATIVE dir]  # If present, the destination package location is determined
21#                   # using the source location relative to the ${dir} (see
22#                   VTK/Web/Python/CMakeLists.txt for usage).
23# )
24# Uses following global variables:
25# VTK_BUILD_PYTHON_MODULE_DIR :- location where the entire package will be
26#           copied and built. Thus, for the above example we'd get a
27#           ${VTK_BUILD_PYTHON_MODULE_DIR}/autobahn package.
28#
29# VTK_INSTALL_PYTHON_MODULE_DIR :- location where the entire package will be
30#           installed if NO_INSTALL is not provided.
31#
32# VTK_INSTALL_NO_RUNTIME :- install rules are skipped if set.
33#------------------------------------------------------------------------------
34function (vtk_module_python_package name)
35  if(NOT "${name}" STREQUAL "${vtk-module}")
36    message(FATAL_ERROR "vtk_module_library must be invoked with module name")
37  endif()
38
39  vtk_module_impl()
40  vtk_module_export("")
41
42  set(_packages)
43  set(_no_install)
44  set(_can_use_system)
45  set(_doing)
46  set(_relative)
47  foreach(arg ${ARGN})
48    if (_doing STREQUAL "RELATIVE")
49      set (_relative "${arg}")
50      set (_doing)
51    elseif(arg STREQUAL "RELATIVE")
52      set (_doing "RELATIVE")
53    elseif(arg STREQUAL "NO_INSTALL")
54      set (_no_install TRUE)
55    elseif(arg STREQUAL "CAN_USE_SYSTEM")
56      set (_can_use_system TRUE)
57    else()
58      list(APPEND _packages "${arg}")
59    endif()
60  endforeach()
61
62  find_package(PythonInterp ${VTK_PYTHON_VERSION} REQUIRED)
63
64  set (_depencies)
65  foreach(pkg ${_packages})
66    get_filename_component(_dir "${pkg}" ABSOLUTE)
67    get_filename_component(_name "${pkg}" NAME)
68    if(_relative)
69      file(RELATIVE_PATH _name_target "${_relative}" "${_dir}")
70    else()
71      set (_name_target "${_name}")
72    endif()
73
74    set (_use_system FALSE)
75    if (_can_use_system)
76      string(TOUPPER "${_name}" _name_upper)
77      option(VTK_USE_SYSTEM_${_name_upper} "Use system '${_name}' Python package" OFF)
78      mark_as_advanced(VTK_USE_SYSTEM_${_name_upper})
79      set (_use_system ${VTK_USE_SYSTEM_${_name_upper}})
80    endif()
81
82    if (NOT _use_system)
83      # copy the sources *.py files to build directory.
84      copy_files_recursive("${_dir}"
85        DESTINATION "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}"
86        LABEL "Copying files for Python package '${_name}'"
87        OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_name}.copy-complete"
88        REGEX "^(.*\\.py)$"
89        )
90
91      add_custom_command(
92        COMMAND ${PYTHON_EXECUTABLE} -m compileall "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}"
93        COMMAND ${PYTHON_EXECUTABLE} -O -m compileall "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}"
94        COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${_name}.build-complete"
95        DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_name}.copy-complete"
96        OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/${_name}.build-complete"
97        COMMENT "Compiling Python package '${_name}'")
98
99      # save the output file so we can add a target for the module with proper
100      # dependency.
101      list(APPEND _depencies "${CMAKE_CURRENT_BINARY_DIR}/${_name}.build-complete")
102
103      # add install rules.
104      if (NOT _no_install AND NOT VTK_INSTALL_NO_RUNTIME)
105        install(DIRECTORY "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}/"
106                DESTINATION "${VTK_INSTALL_PYTHON_MODULE_DIR}/${_name_target}"
107                COMPONENT "Runtime")
108      endif()
109    endif() # NOT _use_system
110  endforeach()
111
112  if (_depencies)
113    add_custom_target(${name} ALL DEPENDS ${_depencies})
114  endif()
115endfunction()
116
117#------------------------------------------------------------------------------
118# This is similar to vtk_module_python_package(), except designed to be used for
119# Python modules (not packages). Modules are simply Py files without any
120# directory structure and __init__.py file.
121# Typical usage:
122# vtk_module_python_module(
123#   SixPython           # name of the vtk-module
124#   six.py              # name of the module py file
125#   ...                 # additional module files.
126#   [NO_INSTALL]        # if present, install rules are skipped.
127#   [CAN_USE_SYSTEM]    # if present, user will be provided with an option to use
128#                       # system module.
129#
130# Uses following global variables:
131# VTK_BUILD_PYTHON_MODULE_DIR :- location where the entire package will be
132#           copied and built. Thus, for the above example we'd get a
133#           ${VTK_BUILD_PYTHON_MODULE_DIR}/autobahn package.
134#
135# VTK_INSTALL_PYTHON_MODULE_DIR :- location where the entire package will be
136#           installed if NO_INSTALL is not provided.
137#
138# VTK_INSTALL_NO_RUNTIME :- install rules are skipped if set.
139#------------------------------------------------------------------------------
140function (vtk_module_python_module name)
141  if(NOT "${name}" STREQUAL "${vtk-module}")
142    message(FATAL_ERROR "vtk_module_library must be invoked with module name")
143  endif()
144
145  vtk_module_impl()
146  vtk_module_export("")
147
148  set(_modules)
149  set(_no_install)
150  set(_can_use_system)
151  foreach(arg ${ARGN})
152    if(arg STREQUAL "NO_INSTALL")
153      set (_no_install TRUE)
154    elseif(arg STREQUAL "CAN_USE_SYSTEM")
155      set (_can_use_system TRUE)
156    else()
157      list(APPEND _modules "${arg}")
158    endif()
159  endforeach()
160
161  find_package(PythonInterp REQUIRED)
162
163  set (_depencies)
164  foreach(mdl ${_modules})
165    get_filename_component(_module "${mdl}" ABSOLUTE)
166    get_filename_component(_name_we   "${mdl}" NAME_WE)
167    get_filename_component(_name   "${mdl}" NAME)
168
169    set (_use_system FALSE)
170    if (_can_use_system)
171      string(TOUPPER "${_name_we}" _name_we_upper)
172      option(VTK_USE_SYSTEM_${_name_we_upper} "Use system '${_name_we}' Python Module" OFF)
173      mark_as_advanced(VTK_USE_SYSTEM_${_name_we_upper})
174      set (_use_system ${VTK_USE_SYSTEM_${_name_we_upper}})
175    endif()
176
177    if (NOT _use_system)
178      # copy the *.py file to the build directory and compile it.
179      add_custom_command(
180        COMMAND ${CMAKE_COMMAND} -E copy ${_module} ${VTK_BUILD_PYTHON_MODULE_DIR}/${_name}
181        COMMAND ${PYTHON_EXECUTABLE} -m py_compile ${VTK_BUILD_PYTHON_MODULE_DIR}/${_name}
182        COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile ${VTK_BUILD_PYTHON_MODULE_DIR}/${_name}
183        COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${_name_we}.build-complete"
184        DEPENDS ${_module}
185        OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/${_name_we}.build-complete"
186        COMMENT "Copying and compiling Python module'${_name_we}'")
187
188      # save the output file so we can add a target for the module with proper
189      # dependency.
190      list(APPEND _depencies "${CMAKE_CURRENT_BINARY_DIR}/${_name_we}.build-complete")
191
192      # add install rules.
193      if (NOT _no_install AND NOT VTK_INSTALL_NO_RUNTIME)
194        install(FILES "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name}"
195                      "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_we}.pyc"
196                      "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_we}.pyo"
197                DESTINATION "${VTK_INSTALL_PYTHON_MODULE_DIR}"
198                COMPONENT "Runtime")
199      endif()
200    endif() # NOT _use_system
201  endforeach()
202
203  if (_depencies)
204    add_custom_target(${name} ALL DEPENDS ${_depencies})
205  endif()
206endfunction()
207