include(vtkPythonPackages) #------------------------------------------------------------------------------ # This file extends vtkModuleMacros.cmake to add support for VTK modules that # are pure Python packages or modules. #------------------------------------------------------------------------------ #------------------------------------------------------------------------------ # Corresponds to vtk_module_library(), instead we're now adding a Python # package. This is designed for packages and hence do not use when dealing with # Python modules. # Typical usage is as follows: # vtk_module_python_package( # AutobahnPython # name of the vtk-module # autobahn # package directory i.e. the directory with __init__.py file. # ... # additional packages. # [NO_INSTALL] # if present, install rules are skipped. # [CAN_USE_SYSTEM] # if present, user will be provided with an option to use # # system package. # [RELATIVE dir] # If present, the destination package location is determined # # using the source location relative to the ${dir} (see # VTK/Web/Python/CMakeLists.txt for usage). # ) # Uses following global variables: # VTK_BUILD_PYTHON_MODULE_DIR :- location where the entire package will be # copied and built. Thus, for the above example we'd get a # ${VTK_BUILD_PYTHON_MODULE_DIR}/autobahn package. # # VTK_INSTALL_PYTHON_MODULE_DIR :- location where the entire package will be # installed if NO_INSTALL is not provided. # # VTK_INSTALL_NO_RUNTIME :- install rules are skipped if set. #------------------------------------------------------------------------------ function (vtk_module_python_package name) if(NOT "${name}" STREQUAL "${vtk-module}") message(FATAL_ERROR "vtk_module_library must be invoked with module name") endif() vtk_module_impl() vtk_module_export("") set(_packages) set(_no_install) set(_can_use_system) set(_doing) set(_relative) foreach(arg ${ARGN}) if (_doing STREQUAL "RELATIVE") set (_relative "${arg}") set (_doing) elseif(arg STREQUAL "RELATIVE") set (_doing "RELATIVE") elseif(arg STREQUAL "NO_INSTALL") set (_no_install TRUE) elseif(arg STREQUAL "CAN_USE_SYSTEM") set (_can_use_system TRUE) else() list(APPEND _packages "${arg}") endif() endforeach() find_package(PythonInterp ${VTK_PYTHON_VERSION} REQUIRED) set (_depencies) foreach(pkg ${_packages}) get_filename_component(_dir "${pkg}" ABSOLUTE) get_filename_component(_name "${pkg}" NAME) if(_relative) file(RELATIVE_PATH _name_target "${_relative}" "${_dir}") else() set (_name_target "${_name}") endif() set (_use_system FALSE) if (_can_use_system) string(TOUPPER "${_name}" _name_upper) option(VTK_USE_SYSTEM_${_name_upper} "Use system '${_name}' Python package" OFF) mark_as_advanced(VTK_USE_SYSTEM_${_name_upper}) set (_use_system ${VTK_USE_SYSTEM_${_name_upper}}) endif() if (NOT _use_system) # copy the sources *.py files to build directory. copy_files_recursive("${_dir}" DESTINATION "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}" LABEL "Copying files for Python package '${_name}'" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_name}.copy-complete" REGEX "^(.*\\.py)$" ) add_custom_command( COMMAND ${PYTHON_EXECUTABLE} -m compileall "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}" COMMAND ${PYTHON_EXECUTABLE} -O -m compileall "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}" COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${_name}.build-complete" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_name}.copy-complete" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_name}.build-complete" COMMENT "Compiling Python package '${_name}'") # save the output file so we can add a target for the module with proper # dependency. list(APPEND _depencies "${CMAKE_CURRENT_BINARY_DIR}/${_name}.build-complete") # add install rules. if (NOT _no_install AND NOT VTK_INSTALL_NO_RUNTIME) install(DIRECTORY "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_target}/" DESTINATION "${VTK_INSTALL_PYTHON_MODULE_DIR}/${_name_target}" COMPONENT "Runtime") endif() endif() # NOT _use_system endforeach() if (_depencies) add_custom_target(${name} ALL DEPENDS ${_depencies}) endif() endfunction() #------------------------------------------------------------------------------ # This is similar to vtk_module_python_package(), except designed to be used for # Python modules (not packages). Modules are simply Py files without any # directory structure and __init__.py file. # Typical usage: # vtk_module_python_module( # SixPython # name of the vtk-module # six.py # name of the module py file # ... # additional module files. # [NO_INSTALL] # if present, install rules are skipped. # [CAN_USE_SYSTEM] # if present, user will be provided with an option to use # # system module. # # Uses following global variables: # VTK_BUILD_PYTHON_MODULE_DIR :- location where the entire package will be # copied and built. Thus, for the above example we'd get a # ${VTK_BUILD_PYTHON_MODULE_DIR}/autobahn package. # # VTK_INSTALL_PYTHON_MODULE_DIR :- location where the entire package will be # installed if NO_INSTALL is not provided. # # VTK_INSTALL_NO_RUNTIME :- install rules are skipped if set. #------------------------------------------------------------------------------ function (vtk_module_python_module name) if(NOT "${name}" STREQUAL "${vtk-module}") message(FATAL_ERROR "vtk_module_library must be invoked with module name") endif() vtk_module_impl() vtk_module_export("") set(_modules) set(_no_install) set(_can_use_system) foreach(arg ${ARGN}) if(arg STREQUAL "NO_INSTALL") set (_no_install TRUE) elseif(arg STREQUAL "CAN_USE_SYSTEM") set (_can_use_system TRUE) else() list(APPEND _modules "${arg}") endif() endforeach() find_package(PythonInterp REQUIRED) set (_depencies) foreach(mdl ${_modules}) get_filename_component(_module "${mdl}" ABSOLUTE) get_filename_component(_name_we "${mdl}" NAME_WE) get_filename_component(_name "${mdl}" NAME) set (_use_system FALSE) if (_can_use_system) string(TOUPPER "${_name_we}" _name_we_upper) option(VTK_USE_SYSTEM_${_name_we_upper} "Use system '${_name_we}' Python Module" OFF) mark_as_advanced(VTK_USE_SYSTEM_${_name_we_upper}) set (_use_system ${VTK_USE_SYSTEM_${_name_we_upper}}) endif() if (NOT _use_system) # copy the *.py file to the build directory and compile it. add_custom_command( COMMAND ${CMAKE_COMMAND} -E copy ${_module} ${VTK_BUILD_PYTHON_MODULE_DIR}/${_name} COMMAND ${PYTHON_EXECUTABLE} -m py_compile ${VTK_BUILD_PYTHON_MODULE_DIR}/${_name} COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile ${VTK_BUILD_PYTHON_MODULE_DIR}/${_name} COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${_name_we}.build-complete" DEPENDS ${_module} OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_name_we}.build-complete" COMMENT "Copying and compiling Python module'${_name_we}'") # save the output file so we can add a target for the module with proper # dependency. list(APPEND _depencies "${CMAKE_CURRENT_BINARY_DIR}/${_name_we}.build-complete") # add install rules. if (NOT _no_install AND NOT VTK_INSTALL_NO_RUNTIME) if(VTK_PYTHON_VERSION VERSION_LESS 3) install(FILES "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name}" "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_we}.pyc" "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name_we}.pyo" DESTINATION "${VTK_INSTALL_PYTHON_MODULE_DIR}" COMPONENT "Runtime") else() # python 3 uses a different directory for .pyc files, and .pyo files are gone. install(FILES "${VTK_BUILD_PYTHON_MODULE_DIR}/${_name}" DESTINATION "${VTK_INSTALL_PYTHON_MODULE_DIR}" COMPONENT "Runtime") file(GLOB file_matches "${VTK_BUILD_PYTHON_MODULE_DIR}/__pycache__/${_name_we}.*.pyc") install(FILES ${file_matches} DESTINATION "${VTK_INSTALL_PYTHON_MODULE_DIR}/__pycache__" COMPONENT "Runtime") endif() endif() endif() # NOT _use_system endforeach() if (_depencies) add_custom_target(${name} ALL DEPENDS ${_depencies}) endif() endfunction()