Wrapper hierarchy file

Hello @ben.boeckel,

I have heard that you are familiar with the wrapper “engine” of VTK and you can help me with a problem of my library. I don’t know how to fix this error:

[ 66%] Python Wrapping - generating vtkboolPythonInit.cxx
make[2]: *** No rule to make target '../vtkboolHierarchy', needed by 'vtkPolyDataBooleanFilterPython.cxx'.  Stop.
make[1]: *** [CMakeFiles/Makefile2:154: CMakeFiles/vtkboolPythonD.dir/all] Error 2
make: *** [Makefile:95: all] Error

It only happens with VTK8. There is an older documentation (https://vtk.org/Wiki/VTK/WrapHierarchy) about it, but that doesn’t help me. I don’t know what is missing.

Here is the link to my project: https://github.com/zippy84/vtkbool

Thanks in advance

I’m not as familiar with the VTK 8.x wrapping CMake APIs (@dgobbi may have better information here). I think you need to call vtk_wrap_hierarchy(${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR} vtkPolyDataBooleanFilter.cxx). Though scoping and expected directories may not be correct there.

Hi Ronald,

For VTK 8, something like this is needed at the top of the VTK_WRAP_PYTHON section:

if(${VTK_MAJOR_VERSION} GREATER 7)
  set(MODULE_HIERARCHY_NAME ${PROJECT_NAME}Hierarchy)
  include(vtkWrapHierarchy)
  vtk_wrap_hierarchy(${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR} vtkPolyDataBooleanFilter.h)
  set(KIT_HIERARCHY_FILE ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.txt)
  set(LIB_HIERARCHY_STAMP ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.stamp.txt)
endif()

@mwestphal told me that.

@dgobbi Thanks, I will try it when I’m home.

@dgobbi It works except for one thing:

21/21 Testing: Test_Py
21/21 Test: Test_Py
Command: "/usr/bin/python3.6" "/home/zippy/vtkbool/testing/test_py_module.py" "/home/zippy/VTK8/lib64/python3.6/site-packages" "/home/zippy/vtkbool/build" "Release"
Directory: /home/zippy/vtkbool/build
"Test_Py" start time: Aug 12 19:49 CEST
Output:
----------------------------------------------------------
Traceback (most recent call last):
  File "/home/zippy/vtkbool/testing/test_py_module.py", line 28, in <module>
    vtkboolPython.vtkPolyDataBooleanFilter()
TypeError: this class cannot be instantiated

The generated vtkboolHierarchy.txt is:

HolesType = std::vector<IdsType> ; vtkPolyDataBooleanFilter.h ; vtkbool
InvolvedType = std::set<int> ; vtkPolyDataBooleanFilter.h ; vtkbool
MergePt ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
PStrips ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
PolyStripsType = std::map<int, PStrips> ; vtkPolyDataBooleanFilter.h ; vtkbool
RefsType = std::vector<std::reference_wrapper<StripPtR> > ; vtkPolyDataBooleanFilter.h ; vtkbool
Rel : enum ; vtkPolyDataBooleanFilter.h ; vtkbool
RelationsType = std::map<int, Rel> ; vtkPolyDataBooleanFilter.h ; vtkbool
StripPt ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
StripPtL ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
StripPtL2 ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
StripPtL3 ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
StripPtR ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
StripPtsType = std::map<int, StripPt> ; vtkPolyDataBooleanFilter.h ; vtkbool
StripType = std::deque<StripPtR> ; vtkPolyDataBooleanFilter.h ; vtkbool
StripsType = std::vector<StripType> ; vtkPolyDataBooleanFilter.h ; vtkbool
_Wrapper ; vtkPolyDataBooleanFilter.h ; vtkbool ; WRAP_EXCLUDE_PYTHON
vtkPolyDataBooleanFilter : vtkPolyDataAlgorithm ; vtkPolyDataBooleanFilter.h ; vtkbool
vtkPolyDataBooleanFilter::Superclass = vtkPolyDataAlgorithm ; vtkPolyDataBooleanFilter.h ; vtkbool

What could be wrong?

Here is the changed CMakeLists.txt: https://github.com/zippy84/vtkbool/blob/hierarchy/CMakeLists.txt

Oops, I missed setting the “WRAP_DEPENDS” variable that vtkWrapHierarchy needs. Try this:

if(${VTK_MAJOR_VERSION} GREATER 7)
  set(MODULE_HIERARCHY_NAME ${PROJECT_NAME}Hierarchy)
  set(${PROJECT_NAME}_WRAP_DEPENDS vtkCommonExecutionModel)
  include(vtkWrapHierarchy)
  vtk_wrap_hierarchy(${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR} vtkPolyDataBooleanFilter.h)
  set(KIT_HIERARCHY_FILE ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.txt)
  set(LIB_HIERARCHY_STAMP ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.stamp.txt)
endif()

@dgobbi It works :slight_smile:

Will there ever be a good documentation about it?

Maybe. If there was good documentation, where would you go to find it? I’m not sure where people look for VTK info these days, other than here and the doxygen pages.

@dgobbi

There is a problem with your code. I tried it under Fedora 30 with VTK 8.1.1 and I still get

make[2]: *** No rule to make target 'vtkbool/vtkboolHierarchy.txt', needed by 'vtkbool/vtkPolyDataBooleanFilterPython.cxx'.  Stop.
make[1]: *** [CMakeFiles/Makefile2:521: vtkbool/CMakeFiles/vtkboolPythonD.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

The vtkboolHierarchy.txt is missing.

Do you have any idea?

Is it working with VTK 8.2, but just not with VTK 8.1?

There is a lot of code churn in VTK’s cmake files from one version of VTK to the next, and wrapping techniques that work with one version often don’t work with others.

For my vtk-dicom project, I wrote a customized vtkWrapHierarchy.cmake in order to get the wrapping to work with multiple versions of VTK. In particular, I suspect the patch needed to fix the “…Hierarchy.txt is missing” error is this one:

https://github.com/dgobbi/vtk-dicom/commit/5606a03

Similar changes were made to VTK’s own vtkWrapHierarchy.cmake for VTK 8.2, but they are absent in VTK 8.1.

With your code I was able to write this:

if(${VTK_VERSION} VERSION_EQUAL "8.1")
    configure_file(
        ${VTK_CMAKE_DIR}/vtkWrapperInit.data.in
        ${MODULE_HIERARCHY_NAME}.data
        @ONLY
    )

    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.txt
            ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.stamp.txt
        COMMAND ${VTK_WRAP_HIERARCHY_EXE} -o ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.txt
                ${MODULE_HIERARCHY_NAME}.data #[[ something is missing here ]]
        COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.stamp.txt
        DEPENDS ${VTK_WRAP_HIERARCHY_EXE}
            ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.data
        VERBATIM)
endif()

This generates the vtkboolHierarchy.txt, but the file is not big enough. What’s missing?

You are missing the “`${OTHER_HIERARCHY_FILES}” argument, which is a list of the hierarchy files for all the libraries that your library links to:

https://github.com/dgobbi/vtk-dicom/blob/5606a03/CMake/vtkWrapHierarchy.cmake#L126

But what are they, in my case? I’m linking with ${VTK_LIBRARIES}. find_package is this find_package(VTK REQUIRED COMPONENTS vtkFiltersSources vtkIOLegacy vtkFiltersExtraction vtkFiltersGeometry vtkFiltersModeling vtkRenderingFreeType OPTIONAL_COMPONENTS vtkWrappingPythonCore NO_MODULE).

Are you saying that there is no vtkbool_LINK_DEPENDS for your library?
What do you get if you try to print its value?

message(STATUS "vtkbool_LINK_DEPENDS ${vtkbool_LINK_DEPENDS}")

Yes, it is empty. I’m currently not using vtk.module and module.cmake. (I’m still waiting for @lorensen PR.)

Ah, I looked through my own code, and it seems that I had to set it myself:

https://github.com/dgobbi/vtk-dicom/blob/5606a03/Source/CMakeLists.txt#L142

Could you please look at my code? I’m unfortunately don’t know what to do :frowning:

Just try setting vtkbool_LINK_DEPENDS and then build the OTHER_HIERARCHY_FILES with the code that I linked. For example,

set(vtkbool_LINK_DEPENDS vtkFiltersSources vtkIOLegacy vtkFiltersExtraction vtkFiltersGeometry vtkFiltersModeling vtkRenderingFreeType)

@dgobbi Thanks for your help! It works :slight_smile:

There is one question left. You are using the args-files in your custom_command. Can you say why? The content is just a list of -I"…" entries.

My code btw:

if(${VTK_MAJOR_VERSION} GREATER 7)
    set(MODULE_HIERARCHY_NAME ${PROJECT_NAME}Hierarchy)
    set(${PROJECT_NAME}_WRAP_DEPENDS vtkCommonExecutionModel)

    set(${PROJECT_NAME}_LINK_DEPENDS vtkCommonExecutionModel)

    include(vtkWrapHierarchy)
    vtk_wrap_hierarchy(${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR} vtkPolyDataBooleanFilter.h)
    set(KIT_HIERARCHY_FILE ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.txt)
    set(LIB_HIERARCHY_STAMP ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.stamp.txt)

    if(${VTK_VERSION} VERSION_EQUAL "8.1")
        configure_file(
            ${VTK_CMAKE_DIR}/vtkWrapperInit.data.in
            ${MODULE_HIERARCHY_NAME}.data
            @ONLY
        )

        set(OTHER_HIERARCHY_FILES)

        foreach(dep ${${PROJECT_NAME}_LINK_DEPENDS})
            list(APPEND OTHER_HIERARCHY_FILES "${${dep}_WRAP_HIERARCHY_FILE}")
        endforeach()

        add_custom_command(OUTPUT ${KIT_HIERARCHY_FILE}
                ${LIB_HIERARCHY_STAMP}
            COMMAND ${VTK_WRAP_HIERARCHY_EXE} -o ${KIT_HIERARCHY_FILE}
                    ${MODULE_HIERARCHY_NAME}.data ${OTHER_HIERARCHY_FILES}
            COMMAND ${CMAKE_COMMAND} -E touch ${LIB_HIERARCHY_STAMP}
            DEPENDS ${VTK_WRAP_HIERARCHY_EXE}
                ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_HIERARCHY_NAME}.data
                ${OTHER_HIERARCHY_FILES}
            VERBATIM)
    endif()

endif()

Glad to hear that it is working. I wasn’t sure if the fedora VTK package would include all of the necessary files.

The “-I...” entries in the args file are used when vtkWrapHierarchy processes “#include” directives. There are some situations where this can be important.

Consider when vtkWrapHierarchy processes a file called vtkMyClass.h that contains this code:

#include "vtkConfigure.h" /* might define VTK_LEGACY_REMOVE */

#ifndef VTK_LEGACY_REMOVE
   /* define a legacy method */
#endif

In this case, vtkWrapHierarchy needs the “-I” args so that it can find vtkConfigure.h, because otherwise it will not know if VTK_LEGACY_REMOVE is defined (it will assume that it is not defined).

Note that VTK_LEGACY_REMOVE is just one example. The “-I” args are needed whenever you are wrapping a header file that needs things that were #define'd in other headers.