COMP: Link the full Python library for wrapped modules where required - #74
Conversation
c44ce00 ("COMP: Only search for Python3 Development.Module component") switched the wrapping to find only Python3 Development.Module, dropped VTK_WRAP_PYTHON_FIND_LIBS, and removed VTK_Python3_LIBRARIES from the wrapped module link line. Development.Module leaves the Python C-API symbols undefined for the host interpreter to provide, which is fine where the linker allows undefined symbols (macOS links MODULE targets with -undefined dynamic_lookup), but on Linux the wrapped modules are linked with -Wl,--no-undefined and must resolve the Python symbols at link time. The result is a link failure of every wrapped Python module, e.g.: vtkAddonMathUtilitiesPython.cxx: undefined reference to `PyTuple_Size' Restore the behavior the removed code provided, gated on VTK_UNDEFINED_SYMBOLS_ALLOWED: keep Development.Module where undefined symbols are allowed, otherwise require the full Development component and link Python3::Python. VTK_WRAP_PYTHON_FIND_LIBS is set again so the block runs, and VTK_Python3_LIBRARIES is re-added to the wrapped module link line. Reproduced and fixed on an Ubuntu 22.04 Slicer superbuild: without the change the inner build fails linking the wrapped modules; with it the full application builds, packages, and runs (the wrapped classes, including inherited base-class methods, work). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
When building Python modules on Linux and Mac it is intended to not link the python lib as the symbols are expected to be provided by running interpreter. To fix the original issue, JCFR indicated that we must add an option to tell VTK to not do this link by default: #27 (comment) Once this option is defined, the VTK::Python target will have the appropriate flags to prevent link errors. |
|
@AlexyPellegrini thanks for looking in to this. The current code works for both mac and linux for today's preview builds of Slicer so we don't want to regress. If you can suggest changes that work for your purposes and don't break Slicer that's good. We discussed with @Thibault-Pelletier yesterday and people can stick to the earlier hash of vtkAddon if this new code is a problem for any projects. |
cc @AlexyPellegrini
Problem
This is the root cause of the current Linux build breakage in Slicer (Slicer/Slicer#9348), which appeared after the SuperBuild vtkAddon bump.
c44ce00("COMP: Only search for Python3 Development.Module component") did three coupled things:find_package(Python3 COMPONENTS Development)→Development.Module,set(VTK_WRAP_PYTHON_FIND_LIBS 1)invtkMacroKitPythonWrap.cmake(so the "find the Python library" block invtkWrapPython.cmakebecame dead andVTK_Python3_LIBRARIESis never set), and${VTK_Python3_LIBRARIES}from bothtarget_link_librariescalls for the wrapped module.Development.Moduleprovides onlyPython3::Module, which deliberately leaves the Python C-API symbols undefined for the host interpreter to supply. That is fine where the linker allows undefined symbols (on macOS,MODULEtargets link with-undefined dynamic_lookup), but on Linux the wrapped modules are linked with-Wl,--no-undefined(vtk_undefined_symbols_allowed=FALSE) and must resolve the Python symbols at link time. The result is a link failure of every wrapped module:Fix
Restore what the removed code provided, gated on
VTK_UNDEFINED_SYMBOLS_ALLOWED: keepDevelopment.Modulewhere undefined symbols are allowed, otherwise require the fullDevelopmentcomponent and linkPython3::Python.VTK_WRAP_PYTHON_FIND_LIBSis set again so the block runs, andVTK_Python3_LIBRARIESis re-added to the wrapped-module link line (both the VTK<8.90 and VTK>=8.90 paths).@AlexyPellegrini — since the
Development.Moduleswitch was intentional, flagging in case you'd prefer instead to exempt the wrappedMODULEtargets from-Wl,--no-undefined(the way VTK's own module wrapper does). This PR takes the more conservative "restore the prior linkage" route to unbreak the dashboards.Testing
Reproduced and fixed on an Ubuntu 22.04 Slicer superbuild (Release, VTK 9.6, Python 3.12): without the change the inner build fails linking the wrapped Python modules; with it, the full application builds, packages, and runs off the build machine — the previously-failing classes (
vtkAddonMathUtilities,vtkSegmentation, …) load, and inherited base-class methods (vtkOrientedGridTransform.SetDisplacementGridData) are present.🤖 Generated with Claude Code