From 59bad275457d2576a26249f1f209913a2988b2ab Mon Sep 17 00:00:00 2001 From: Steve Pieper Date: Mon, 10 Aug 2026 14:05:20 -0400 Subject: [PATCH] COMP: Link the full Python library for wrapped modules where required 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 --- CMake/vtkMacroKitPythonWrap.cmake | 3 +++ CMake/vtkWrapPython.cmake | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CMake/vtkMacroKitPythonWrap.cmake b/CMake/vtkMacroKitPythonWrap.cmake index 3d03454..6f48852 100644 --- a/CMake/vtkMacroKitPythonWrap.cmake +++ b/CMake/vtkMacroKitPythonWrap.cmake @@ -159,6 +159,7 @@ macro(vtkMacroKitPythonWrap) endif() if(VTK_WRAP_PYTHON AND BUILD_SHARED_LIBS) + set(VTK_WRAP_PYTHON_FIND_LIBS 1) include(vtkWrapPython) set(TMP_WRAP_FILES ${MY_KIT_SRCS} ${MY_KIT_WRAP_HEADERS}) @@ -280,6 +281,7 @@ macro(vtkMacroKitPythonWrap) ${MY_KIT_NAME}PythonD ${MY_KIT_NAME} ${VTK_PYTHON_CORE} + ${VTK_Python3_LIBRARIES} ${VTK_KIT_PYTHON_LIBRARIES} ${MY_KIT_PYTHON_LIBRARIES} ) @@ -340,6 +342,7 @@ macro(vtkMacroKitPythonWrap) target_link_libraries(${MY_KIT_NAME}Python PRIVATE ${MY_KIT_NAME} + ${VTK_Python3_LIBRARIES} VTK::WrappingPythonCore VTK::Python ) diff --git a/CMake/vtkWrapPython.cmake b/CMake/vtkWrapPython.cmake index 76f48da..c1c8f0c 100644 --- a/CMake/vtkWrapPython.cmake +++ b/CMake/vtkWrapPython.cmake @@ -233,7 +233,18 @@ $<$>: endmacro() if(VTK_WRAP_PYTHON_FIND_LIBS) - find_package(Python3 COMPONENTS Development.Module REQUIRED) + # Development.Module leaves the Python C-API symbols undefined for the host + # interpreter to provide. That is fine where the linker allows undefined + # symbols (macOS -undefined dynamic_lookup), but on Linux the wrapped modules + # link with -Wl,--no-undefined and must resolve the Python symbols at link + # time, so the full library (Python3::Python) is required there. + if(VTK_UNDEFINED_SYMBOLS_ALLOWED) + find_package(Python3 COMPONENTS Development.Module REQUIRED) + set(VTK_Python3_LIBRARIES "") + else() + find_package(Python3 COMPONENTS Development REQUIRED) + set(VTK_Python3_LIBRARIES Python3::Python) + endif() endif() # Determine the location of the supplied header in the include_dirs supplied.