Skip to content

Commit

Permalink
python: Add wrapping of kits when VTK_ENABLE_KITS is ON
Browse files Browse the repository at this point in the history
If VTK_ENABLE_KITS is ON, VTK kits and modules that are not associated with any
kit will be wrapped. The effect is that drastically fewer libraries are created.

Take vtkCommon as an example. When VTK_ENABLE_KITS is OFF, a library is
generated for each wrapped module:

    vtkCommonColorPython27D-x.y.dll
    vtkCommonComputationalGeometryPython27D-x.y.dll
    vtkCommonCorePython27D-x.y.dll
    vtkCommonDataModelPython27D-x.y.dll
    vtkCommonExecutionModelPython27D-x.y.dll
    vtkCommonMathPython27D-x.y.dll
    vtkCommonMiscPython27D-x.y.dll
    vtkCommonSystemPython27D-x.y.dll
    vtkCommonTransformsPython27D-x.y.dll

When VTK_ENABLE_KITS is ON, a single "kit" library is generated:

    vtkCommonKitPython27D-x.y.dll

The wrapped kits have the suffix "Kit" to avoid naming conflicts with existing
libraries like "vtkFilterPython".

As part of this change, the Python wrapping function has been split into two
functions, one which wraps the code and another which builds the wrapped code.
The new function is backwards compatible, but to update client code, replace
calls like:

    vtk_add_python_wrapping(${module})

with:

    vtk_add_python_wrapping(${module} module_srcs)
    vtk_add_python_wrapping_library(${module} module_srcs ${module})

Additionally, the functions "vtk_wrap_python" and "vtk_add_python_wrapping" have
been updated to understand a list of modules as input.

Co-authored-by: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
Co-authored-by: Max Smolens <max.smolens@kitware.com>
Co-authored-by: Ben Boeckel <ben.boeckel@kitware.com>
  • Loading branch information
3 people committed Feb 25, 2016
1 parent 3a0ed04 commit 1ebfa5b
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 58 deletions.
1 change: 1 addition & 0 deletions CMake/VTKConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ SET(VTK_WRAP_PYTHON "@VTK_WRAP_PYTHON@")
SET(VTK_WRAP_TCL "@VTK_WRAP_TCL@")
SET(VTK_WRAP_JAVA "@VTK_WRAP_JAVA@")
SET(VTK_QT_VERSION "@VTK_QT_VERSION@")
SET(VTK_ENABLE_KITS "@VTK_ENABLE_KITS@")

# Do not add options or information here that is specific to a
# particular module. Instead set <module>_EXPORT_OPTIONS and/or
Expand Down
2 changes: 2 additions & 0 deletions CMake/vtkModuleTop.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ if(VTK_ENABLE_KITS)
endforeach()
endforeach()

list(REMOVE_DUPLICATES vtk_kits)

# Put all kits in the list (if they are not dependencies of any module, they
# will be dropped otherwise).
list(APPEND vtk_modules_and_kits ${vtk_kits})
Expand Down
115 changes: 84 additions & 31 deletions CMake/vtkPythonWrapping.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,72 +8,125 @@ if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND)
endif()
endif()

function(vtk_add_python_wrapping module_name)
# To support wrapping of either module or kit, this function
# has two signatures:
# 1) vtk_add_python_wrapping(<module_name> <sources_var>)
# 2) vtk_add_python_wrapping("<module_name>[ <module_name>]" <sources_var> <kit_name>)
#
# Legacy code may call this function with a single argument. In that case,
# vtk_add_python_wrapping_library() is called internally to maintain backwards
# compatibility.
function(vtk_add_python_wrapping module_names)
if(${ARGC} EQUAL 1)
set(_legacy TRUE)
message(AUTHOR_WARNING
"Calling vtk_add_python_wrapping() with a single argument is deprecated.\n"
"Replace calls like:\n"
" vtk_add_python_wrapping(\${module})\n"
"with:\n"
" vtk_add_python_wrapping(\${module} module_srcs)\n"
" vtk_add_python_wrapping_library(\${module} module_srcs \${module})")
endif()
if("${ARGV1}" MATCHES ".+")
set(sources_var ${ARGV1})
endif()
if("${ARGV2}" MATCHES ".+")
list(REMOVE_AT ARGN 0)
set(target ${ARGN})
else()
set(target ${module_names})
endif()
if(NOT VTK_WRAP_PYTHON_INIT_EXE)
if(TARGET vtkWrapPythonInit)
set (VTK_WRAP_PYTHON_INIT_EXE vtkWrapPythonInit)
else()
message(FATAL_ERROR "VTK must be built with Python wrapping turned on.")
endif()
endif()

set(EXTRA_PYTHON_INCLUDE_DIRS)
set(KIT_HIERARCHY_FILE)
set(VTK_WRAP_HINTS_FILES)

foreach(module_name IN LISTS module_names)
list(APPEND EXTRA_PYTHON_INCLUDE_DIRS ${${module_name}_PYTHON_INCLUDE_DIRS})

if(NOT ${module_name}_EXCLUDE_FROM_WRAP_HIERARCHY)
list(APPEND KIT_HIERARCHY_FILE ${${module_name}_WRAP_HIERARCHY_FILE})
endif()

if(${module_name}_WRAP_HINTS AND EXISTS "${${module_name}_WRAP_HINTS}")
list(APPEND VTK_WRAP_HINTS_FILES "${${module_name}_WRAP_HINTS}")
endif()
endforeach()

if(VTK_WRAP_HINTS_FILES)
set(VTK_WRAP_HINTS ${VTK_WRAP_HINTS_FILES})
endif()

vtk_wrap_python(${target}Python Python_SRCS "${module_names}")
if(_legacy)
set(_sources "${Python_SRCS}" "${extra_srcs}")
vtk_add_python_wrapping_library(${module_names} _sources ${module_names})
else()
set(${sources_var} "${Python_SRCS}" "${extra_srcs}" PARENT_SCOPE)
endif()
endfunction()

function(vtk_add_python_wrapping_library module srcs)
# Need to add the Wrapping/Python to the include directory
set(_python_include_dirs
${VTK_SOURCE_DIR}/Wrapping/Python
${VTK_BINARY_DIR}/Wrapping/Python
${VTK_SOURCE_DIR}/Utilities/Python
${VTK_BINARY_DIR}/Utilities/Python
${PYTHON_INCLUDE_DIRS})
set(XY ${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION})

if(NOT CMAKE_HAS_TARGET_INCLUDES)
include_directories(${_python_include_dirs})
endif()

if(NOT ${module_name}_EXCLUDE_FROM_WRAP_HIERARCHY)
set(KIT_HIERARCHY_FILE ${${module_name}_WRAP_HIERARCHY_FILE})
endif()

string(REGEX REPLACE "^vtk" "" kit_name "${module_name}")
set(KIT ${kit_name})
set(XY ${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION})

# Figure out the dependent PythonXYD libraries for the module
unset(extra_links)
set(EXTRA_PYTHON_INCLUDE_DIRS ${${module_name}_PYTHON_INCLUDE_DIRS})
foreach(dep ${${module_name}_DEPENDS})
if(NOT "${module_name}" STREQUAL "${dep}" AND TARGET ${dep}PythonD)
set(extra_links)
foreach(dep IN LISTS ${module}_DEPENDS)
if(NOT "${module}" STREQUAL "${dep}" AND TARGET ${dep}PythonD)
list(APPEND extra_links ${dep}PythonD)
endif()
endforeach()

if(${module_name}_WRAP_HINTS AND EXISTS "${${module_name}_WRAP_HINTS}")
set(VTK_WRAP_HINTS "${${module_name}_WRAP_HINTS}")
endif()

vtk_wrap_python(${module_name}Python Python_SRCS ${module_name})
vtk_add_library(${module_name}PythonD ${Python_SRCS} ${extra_srcs})
get_property(output_name TARGET ${module_name}PythonD PROPERTY OUTPUT_NAME)
vtk_add_library(${module}PythonD ${${srcs}})
get_property(output_name TARGET ${module}PythonD PROPERTY OUTPUT_NAME)
string(REPLACE "PythonD" "Python${XY}D" output_name "${output_name}")
set_property(TARGET ${module_name}PythonD PROPERTY OUTPUT_NAME ${output_name})
set_property(TARGET ${module}PythonD PROPERTY OUTPUT_NAME ${output_name})
if(CMAKE_HAS_TARGET_INCLUDES)
set_property(TARGET ${module_name}PythonD APPEND
set_property(TARGET ${module}PythonD APPEND
PROPERTY INCLUDE_DIRECTORIES ${_python_include_dirs})
endif()
if(${module_name}_IMPLEMENTS)
set_property(TARGET ${module_name}PythonD PROPERTY COMPILE_DEFINITIONS
"${module_name}_AUTOINIT=1(${module_name})")
endif()
target_link_libraries(${module_name}PythonD LINK_PUBLIC ${module_name}
target_link_libraries(${module}PythonD LINK_PUBLIC
vtkWrappingPythonCore ${extra_links} ${VTK_PYTHON_LIBRARIES})

if (MSVC)
set_target_properties(${module_name}PythonD
set_target_properties(${module}PythonD
PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_MODULE_LINKER_FLAGS})
endif()

_vtk_add_python_module(${module_name}Python ${module_name}PythonInit.cxx)
target_link_libraries(${module_name}Python ${module_name}PythonD)
foreach (submodule IN LISTS ARGN)
if(${submodule}_IMPLEMENTS)
set_property(TARGET ${module}PythonD APPEND PROPERTY COMPILE_DEFINITIONS
"${submodule}_AUTOINIT=1(${submodule})")
endif()
target_link_libraries(${module}PythonD LINK_PUBLIC ${submodule})
endforeach ()

set(prefix ${module})
if(_${module}_is_kit)
set(prefix ${prefix}${VTK_KIT_SUFFIX})
endif()
_vtk_add_python_module(${module}Python ${prefix}PythonInit.cxx)
target_link_libraries(${module}Python ${module}PythonD)
if(CMAKE_HAS_TARGET_INCLUDES)
set_property(TARGET ${module_name}Python APPEND
set_property(TARGET ${module}Python APPEND
PROPERTY INCLUDE_DIRECTORIES ${_python_include_dirs})
endif()
endfunction()
Expand Down
42 changes: 27 additions & 15 deletions CMake/vtkWrapPython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ macro(VTK_WRAP_PYTHON3 TARGET SRC_LIST_NAME SOURCES)

# collect the common wrapper-tool arguments
set(_common_args)
if(VTK_WRAP_HINTS)
set(_common_args "${_common_args}--hints \"${VTK_WRAP_HINTS}\"\n")
endif()
if(KIT_HIERARCHY_FILE)
set(_common_args "${_common_args}--types \"${KIT_HIERARCHY_FILE}\"\n")
endif()
foreach(file IN LISTS VTK_WRAP_HINTS)
set(_common_args "${_common_args}--hints \"${file}\"\n")
endforeach()
foreach(file IN LISTS KIT_HIERARCHY_FILE)
set(_common_args "${_common_args}--types \"${file}\"\n")
endforeach()

if(NOT CMAKE_VERSION VERSION_LESS 3.1 AND NOT VTK_ENABLE_KITS)
# write wrapper-tool arguments to a file
Expand All @@ -56,13 +56,21 @@ $<$<BOOL:$<TARGET_PROPERTY:${TARGET},INCLUDE_DIRECTORIES>>:
")
else()
# all the include directories
string(REGEX REPLACE "Python\$" "" module "${TARGET}")
if(${module}_INCLUDE_DIRS)
set(TMP_INCLUDE_DIRS ${${module}_INCLUDE_DIRS})
elseif(VTK_WRAP_INCLUDE_DIRS)
set(TMP_INCLUDE_DIRS ${VTK_WRAP_INCLUDE_DIRS})
set(TMP_INCLUDE_DIRS)
set(_modules ${ARGN})
if(NOT _modules)
string(REGEX REPLACE "Python\$" "" module "${TARGET}")
set(_modules ${module})
endif()
foreach(module IN LISTS ${_modules})
if(${module}_INCLUDE_DIRS)
list(APPEND TMP_INCLUDE_DIRS ${${module}_INCLUDE_DIRS})
endif()
endforeach()
if(VTK_WRAP_INCLUDE_DIRS)
list(APPEND TMP_INCLUDE_DIRS ${VTK_WRAP_INCLUDE_DIRS})
else()
set(TMP_INCLUDE_DIRS ${VTK_INCLUDE_DIRS})
list(APPEND TMP_INCLUDE_DIRS ${VTK_INCLUDE_DIRS})
endif()
if(EXTRA_PYTHON_INCLUDE_DIRS)
list(APPEND TMP_INCLUDE_DIRS ${EXTRA_PYTHON_INCLUDE_DIRS})
Expand Down Expand Up @@ -220,11 +228,13 @@ macro(vtk_find_header header include_dirs full_path)
endforeach()
endmacro()

# Macro that just takes the name of the module, figure the rest out from there.
macro(vtk_wrap_python TARGET SRC_LIST_NAME module)
# Macro that just takes the a list of module names, figure the rest out from there.
macro(vtk_wrap_python TARGET SRC_LIST_NAME)
# List of all headers to wrap.
set(headers_to_wrap)

foreach(module ${ARGN})

# Decide what to do for each header.
foreach(header ${${module}_HEADERS})
# Everything in this block is for headers that will be wrapped.
Expand All @@ -241,6 +251,8 @@ macro(vtk_wrap_python TARGET SRC_LIST_NAME module)
endif()
endforeach()

endforeach() # end ARGN loop

# Delegate to vtk_wrap_python3
vtk_wrap_python3(${TARGET} ${SRC_LIST_NAME} "${headers_to_wrap}")
vtk_wrap_python3(${TARGET} ${SRC_LIST_NAME} "${headers_to_wrap}" ${ARGN})
endmacro()
Loading

0 comments on commit 1ebfa5b

Please sign in to comment.