Skip to content

Fix SEGV w/ python and conda on macOS #394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 7 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,14 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-11, windows-2019]
sofa_branch: [master]
python_version: ['3.8']
os: [ubuntu-22.04, macos-13, windows-2022]
sofa_branch: [v23.12]
python_version: ['3.10']

steps:
- name: (Mac) Workaround for homebrew
shell: bash
if: runner.os == 'macOS'
run: |
rm -f /usr/local/bin/2to3
rm -f /usr/local/bin/idle3
rm -f /usr/local/bin/pydoc3
rm -f /usr/local/bin/python3
rm -f /usr/local/bin/python3-config
rm -f /usr/local/bin/2to3-3.11
rm -f /usr/local/bin/idle3.11
rm -f /usr/local/bin/pydoc3.11
rm -f /usr/local/bin/python3.11
rm -f /usr/local/bin/python3.11-config

- name: Setup SOFA and environment
id: sofa
uses: sofa-framework/sofa-setup-action@v4
uses: sofa-framework/sofa-setup-action@v5
with:
sofa_root: ${{ github.workspace }}/sofa
sofa_version: ${{ matrix.sofa_branch }}
Expand All @@ -66,7 +51,7 @@ jobs:
cmake_options="-GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$WORKSPACE_INSTALL_PATH" \
-DCMAKE_PREFIX_PATH="$SOFA_ROOT/lib/cmake" \
-DCMAKE_PREFIX_PATH="$SOFA_ROOT/lib/cmake:$pybind11_DIR" \
-DPYTHON_ROOT=$PYTHON_ROOT -DPython_ROOT=$PYTHON_ROOT \
-DPYTHON_EXECUTABLE=$PYTHON_EXE -DPython_EXECUTABLE=$PYTHON_EXE"
if [ -e "$(command -v ccache)" ]; then
Expand Down Expand Up @@ -98,7 +83,7 @@ jobs:
if [[ "${{ github.event.inputs.is_nightly }}" == "true" ]]; then
ARTIFACT_VERSION="${ARTIFACT_VERSION}-nightly"
fi
ARTIFACT_NAME="${PROJECT_NAME}_${ARTIFACT_VERSION}_python-${{ matrix.python_version }}_for-SOFA-${{ matrix.sofa_branch }}_${{ runner.os }}"
ARTIFACT_NAME="${PROJECT_NAME}_${ARTIFACT_VERSION}_python-${{ matrix.python_version }}_for-SOFA-${{ steps.sofa.outputs.sofa_version }}_${{ runner.os }}"
echo "ARTIFACT_NAME=$ARTIFACT_NAME" | tee -a $GITHUB_ENV

- name: Create artifact
Expand Down Expand Up @@ -177,7 +162,7 @@ jobs:

deploy:
name: Deploy artifacts
if: always() && startsWith(github.ref, 'refs/heads/') # we are on a branch (not a PR)
if: always() && startsWith(github.repository, 'sofa-framework') && (startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/tags/')) # we are not on a fork and on a branch or a tag (not a PR)
needs: [build-and-test]
runs-on: ubuntu-latest
continue-on-error: true
Expand Down
37 changes: 1 addition & 36 deletions CMake/SofaPython3Tools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -114,44 +114,9 @@ function(SP3_add_python_module)

find_package(pybind11 CONFIG QUIET REQUIRED)

# We are doing manually what's usually done with pybind11_add_module(${A_TARGET} SHARED "${A_SOURCES}")
# since we got some problems on MacOS using recent versions of pybind11 where the SHARED argument wasn't taken
# into account
python_add_library(${A_TARGET} SHARED "${A_SOURCES}")
pybind11_add_module(${A_TARGET} SHARED "${A_SOURCES}")
add_library(SofaPython3::${A_TARGET} ALIAS ${A_TARGET})

if ("${pybind11_VERSION}" VERSION_GREATER_EQUAL "2.6.0")
target_link_libraries(${A_TARGET} PRIVATE pybind11::headers)
target_link_libraries(${A_TARGET} PRIVATE pybind11::embed)
target_link_libraries(${A_TARGET} PRIVATE pybind11::lto)
if(MSVC)
target_link_libraries(${A_TARGET} PRIVATE pybind11::windows_extras)
endif()

pybind11_extension(${A_TARGET})
pybind11_strip(${A_TARGET})
else()
target_link_libraries(${A_TARGET} PRIVATE pybind11::module)

# Equivalent to pybind11_extension(${A_TARGET}) which doesn't exists on pybind11 versions < 5
set_target_properties(${A_TARGET} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}")

if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
# Equivalent to pybind11_strip(${A_TARGET}) which doesn't exists on pybind11 versions < 5
# Strip unnecessary sections of the binary on Linux/macOS
if(CMAKE_STRIP)
if(APPLE)
set(x_opt -x)
endif()

add_custom_command(
TARGET ${A_TARGET}
POST_BUILD
COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${A_TARGET}>)
endif()
endif()
endif()

set_target_properties(${A_TARGET}
PROPERTIES
CXX_VISIBILITY_PRESET "hidden"
Expand Down
36 changes: 0 additions & 36 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,34 +82,6 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Set the minimum python version to 3.7
set(PYBIND11_PYTHON_VERSION 3.7)

# Find Python3
find_package(Python ${PYBIND11_PYTHON_VERSION} COMPONENTS Interpreter Development REQUIRED)

# Save PYTHON_* vars
set(PYTHON_VERSION_RESET "${PYTHON_VERSION}")
set(PYTHON_EXECUTABLE_RESET "${PYTHON_EXECUTABLE}")
set(PYTHON_LIBRARIES_RESET "${PYTHON_LIBRARIES}")
set(PYTHON_INCLUDE_DIRS_RESET "${PYTHON_INCLUDE_DIRS}")
set(PYTHON_LIBRARY_RESET "${PYTHON_LIBRARY}")
set(PYTHON_INCLUDE_DIR_RESET "${PYTHON_INCLUDE_DIR}")

# Change PYTHON_* vars before pybind11 find_package
# to be sure that pybind11 relies on the right Python version
set(PYTHON_VERSION "${Python_VERSION}" CACHE STRING "" FORCE)
set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}" CACHE FILEPATH "" FORCE)
set(PYTHON_LIBRARIES "${Python_LIBRARIES}" CACHE STRING "" FORCE)
set(PYTHON_INCLUDE_DIRS "${Python_INCLUDE_DIRS}" CACHE STRING "" FORCE)
if(EXISTS "${Python_LIBRARY}")
set(PYTHON_LIBRARY "${Python_LIBRARY}" CACHE INTERNAL "" FORCE)
elseif(EXISTS "${Python_LIBRARIES}")
set(PYTHON_LIBRARY "${Python_LIBRARIES}" CACHE INTERNAL "" FORCE)
endif()
if(EXISTS "${Python_INCLUDE_DIR}")
set(PYTHON_INCLUDE_DIR "${Python_INCLUDE_DIR}" CACHE INTERNAL "" FORCE)
elseif(EXISTS "${Python_INCLUDE_DIRS}")
set(PYTHON_INCLUDE_DIR "${Python_INCLUDE_DIRS}" CACHE INTERNAL "" FORCE)
endif()

# Set the minimum pybind11 version to 2.3 (before that the pybind11::embed target did not exist)
find_package(pybind11 2.3 CONFIG QUIET REQUIRED)

Expand Down Expand Up @@ -243,11 +215,3 @@ if (SP3_LINK_TO_USER_SITE AND SP3_PYTHON_PACKAGES_LINK_DIRECTORY)
endif()
endforeach()
endif()

# Reset PYTHON_* vars
set(PYTHON_VERSION "${PYTHON_VERSION_RESET}" CACHE STRING "" FORCE)
set(PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE_RESET}" CACHE FILEPATH "" FORCE)
set(PYTHON_LIBRARIES "${PYTHON_LIBRARIES_RESET}" CACHE STRING "" FORCE)
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS_RESET}" CACHE STRING "" FORCE)
set(PYTHON_LIBRARY "${PYTHON_LIBRARY_RESET}" CACHE INTERNAL "" FORCE)
set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR_RESET}" CACHE INTERNAL "" FORCE)
12 changes: 11 additions & 1 deletion Plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,17 @@ add_library(SofaPython3::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
target_compile_definitions(${PROJECT_NAME} PRIVATE "-DSOFA_BUILD_SOFAPYTHON3")

target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Simulation.Graph)
target_link_libraries(${PROJECT_NAME} PUBLIC pybind11::module pybind11::embed)

# The public linking with pybind lead to have a link with libpython which
# propagates in the python module .so. On macOS, this extra link with libpython
# lead to segv when importing the python module in versions of python that don't
# have a dynamic link with libpython (such as the one provided by conda which is linked
# statically), but works fine with versions that have such link.
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
target_link_libraries(${PROJECT_NAME} PRIVATE pybind11::pybind11 pybind11::python_link_helper)
else()
target_link_libraries(${PROJECT_NAME} PUBLIC pybind11::embed)
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME SofaPython3)

Expand Down
37 changes: 0 additions & 37 deletions SofaPython3Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,10 @@ set(SP3_PYTHON_PACKAGES_DIRECTORY @SP3_PYTHON_PACKAGES_DIRECTORY@)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
include(SofaPython3Tools)

# Find Python3
if(NOT Python_FOUND)
find_package(Python @Python_VERSION@ QUIET REQUIRED COMPONENTS Interpreter Development)
endif()

# Find pybind11
if(NOT pybind11_FOUND)
# Save PYTHON_* vars
set(PYTHON_VERSION_RESET "${PYTHON_VERSION}")
set(PYTHON_EXECUTABLE_RESET "${PYTHON_EXECUTABLE}")
set(PYTHON_LIBRARIES_RESET "${PYTHON_LIBRARIES}")
set(PYTHON_INCLUDE_DIRS_RESET "${PYTHON_INCLUDE_DIRS}")
set(PYTHON_LIBRARY_RESET "${PYTHON_LIBRARY}")
set(PYTHON_INCLUDE_DIR_RESET "${PYTHON_INCLUDE_DIR}")

# Change PYTHON_* vars before pybind11 find_package
# to be sure that pybind11 relies on the right Python version
set(PYTHON_VERSION "${Python_VERSION}" CACHE STRING "" FORCE)
set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}" CACHE FILEPATH "" FORCE)
set(PYTHON_LIBRARIES "${Python_LIBRARIES}" CACHE STRING "" FORCE)
set(PYTHON_INCLUDE_DIRS "${Python_INCLUDE_DIRS}" CACHE STRING "" FORCE)
if(EXISTS "${Python_LIBRARY}")
set(PYTHON_LIBRARY "${Python_LIBRARY}" CACHE INTERNAL "" FORCE)
elseif(EXISTS "${Python_LIBRARIES}")
set(PYTHON_LIBRARY "${Python_LIBRARIES}" CACHE INTERNAL "" FORCE)
endif()
if(EXISTS "${Python_INCLUDE_DIR}")
set(PYTHON_INCLUDE_DIR "${Python_INCLUDE_DIR}" CACHE INTERNAL "" FORCE)
elseif(EXISTS "${Python_INCLUDE_DIRS}")
set(PYTHON_INCLUDE_DIR "${Python_INCLUDE_DIRS}" CACHE INTERNAL "" FORCE)
endif()

find_package(pybind11 @pybind11_VERSION@ QUIET REQUIRED CONFIG)

# Reset PYTHON_* vars
set(PYTHON_VERSION "${PYTHON_VERSION_RESET}" CACHE STRING "" FORCE)
set(PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE_RESET}" CACHE FILEPATH "" FORCE)
set(PYTHON_LIBRARIES "${PYTHON_LIBRARIES_RESET}" CACHE STRING "" FORCE)
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS_RESET}" CACHE STRING "" FORCE)
set(PYTHON_LIBRARY "${PYTHON_LIBRARY_RESET}" CACHE INTERNAL "" FORCE)
set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR_RESET}" CACHE INTERNAL "" FORCE)
endif()

# Find SofaPython3::XXXXX
Expand Down
5 changes: 5 additions & 0 deletions Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ set(SOURCE_FILES

add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Testing SofaPython3::Plugin)
# We wan't the pybind11 dependency to propagate to SofaPython3Testing consumers,
# here Bindings.*.Tests
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
target_link_libraries(${PROJECT_NAME} PUBLIC pybind11::embed)
endif()
target_compile_definitions(${PROJECT_NAME} PRIVATE "-DSOFA_BUILD_SOFAPYTHON3")
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Testing)

Expand Down