From c538993a7ccabb9a189beff495ba1745a3392e91 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 7 Aug 2026 00:18:37 -0400 Subject: [PATCH] fix(cmake): don't link SHARED modules against libpython in FindPython mode Python_add_library() hard-links non-MODULE libraries against Python::Python. On macOS with a statically linked interpreter (e.g. uv / python-build-standalone), importing such a module loads a second, uninitialized copy of the Python runtime and aborts with a fatal PyInterpreterState_Get error. Bypass python_add_library for SHARED and link pybind11::module instead of pybind11::embed, matching the classic pybind11Tools.cmake behavior. Assisted-by: ClaudeCode:claude-fable-5 --- tools/pybind11NewTools.cmake | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/pybind11NewTools.cmake b/tools/pybind11NewTools.cmake index b0fe20768d..f9202b9b93 100644 --- a/tools/pybind11NewTools.cmake +++ b/tools/pybind11NewTools.cmake @@ -266,7 +266,13 @@ function(pybind11_add_module target_name) set(lib_type MODULE) endif() - if("${_Python}" STREQUAL "Python") + if(lib_type STREQUAL "SHARED") + # Bypass python_add_library, which links SHARED libraries against libpython. + # An extension module must not link libpython on macOS; with a statically + # linked interpreter (e.g. python-build-standalone) that loads a second + # Python runtime and aborts on import. Matches classic pybind11Tools.cmake. + add_library(${target_name} SHARED ${ARG_UNPARSED_ARGUMENTS}) + elseif("${_Python}" STREQUAL "Python") python_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS}) elseif("${_Python}" STREQUAL "Python3") python3_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS}) @@ -276,10 +282,10 @@ function(pybind11_add_module target_name) target_link_libraries(${target_name} PRIVATE pybind11::headers) - if(lib_type STREQUAL "MODULE") - target_link_libraries(${target_name} PRIVATE pybind11::module) - else() + if(lib_type STREQUAL "STATIC") target_link_libraries(${target_name} PRIVATE pybind11::embed) + else() + target_link_libraries(${target_name} PRIVATE pybind11::module) endif() # -fvisibility=hidden is required to allow multiple modules compiled against