summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorRyan Volz <ryan.volz@gmail.com>2021-01-08 15:43:41 -0500
committerMartin Braun <martin@gnuradio.org>2021-01-14 04:08:21 -0800
commit51d3ad973292763a6fc0cf8e971faa3cf89029e9 (patch)
treeac7e74ccc60615b700f693241379dedd77abbd4e /cmake
parent518dc7eda3a2575292dc67374cad62c887f83d12 (diff)
cmake: python: Fix linking when runtime py interpreter != build time.
This fixes a segmentation fault with the Pybind11 bindings when trying to load any Python module on OSX with a different interpreter than was used at build time (relevant to at least conda and homebrew). This fix was already in place for the prior Swig bindings, but the Pybind11 changes do not incorporate it since they link with ${PYTHON_LIBRARIES} instead of the (fixed) Python::Python target. For clearer separation and to adopt the approach used by the new-ish (3.12) builtin CMake FindPython module, this commit creates a separate Python::Module target to be used when creating a Python extension module (which includes "-undefined" and "dynamic_lookup" for macOS instead of linking directly to the Python library). The Python::Python target that does link to the Python library is still necessary for use as a PRIVATE target (e.g. for runtime and qtgui). For future reference and a general description of best practices for linking Python extension modules, see https://blog.tim-smith.us/2015/09/python-extension-modules-os-x. Signed-off-by: Ryan Volz <ryan.volz@gmail.com>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/Modules/GrPybind.cmake6
-rw-r--r--cmake/Modules/GrPython.cmake36
2 files changed, 33 insertions, 9 deletions
diff --git a/cmake/Modules/GrPybind.cmake b/cmake/Modules/GrPybind.cmake
index 3eb01c8cdc..bc92a5af3e 100644
--- a/cmake/Modules/GrPybind.cmake
+++ b/cmake/Modules/GrPybind.cmake
@@ -39,7 +39,7 @@ target_include_directories(${name}_python PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/${updir}/include
${PYBIND11_INCLUDE_DIR}
)
-target_link_libraries(${name}_python PUBLIC ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} gnuradio-${MODULE_NAME})
+target_link_libraries(${name}_python PUBLIC ${Boost_LIBRARIES} Python::Module gnuradio-${MODULE_NAME})
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(${name}_python PRIVATE -Wno-unused-variable) # disable warnings for docstring templates
@@ -156,7 +156,7 @@ target_include_directories(${name}_python PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/${updir}/include
${PYBIND11_INCLUDE_DIR}
)
-target_link_libraries(${name}_python PUBLIC ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} gnuradio-${MODULE_NAME})
+target_link_libraries(${name}_python PUBLIC ${Boost_LIBRARIES} Python::Module gnuradio-${MODULE_NAME})
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(${name}_python PRIVATE -Wno-unused-variable) # disable warnings for docstring templates
@@ -289,7 +289,7 @@ target_include_directories(${name}_python PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/${updir}/include
${PYBIND11_INCLUDE_DIR}
)
-target_link_libraries(${name}_python PUBLIC ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} gnuradio-${MODULE_NAME})
+target_link_libraries(${name}_python PUBLIC ${Boost_LIBRARIES} Python::Module gnuradio-${MODULE_NAME})
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(${name}_python PRIVATE -Wno-unused-variable) # disable warnings for docstring templates
diff --git a/cmake/Modules/GrPython.cmake b/cmake/Modules/GrPython.cmake
index ff7927c05a..8149cb5cbe 100644
--- a/cmake/Modules/GrPython.cmake
+++ b/cmake/Modules/GrPython.cmake
@@ -37,14 +37,9 @@ set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests")
add_library(Python::Python INTERFACE IMPORTED)
-if(APPLE)
- set_target_properties(Python::Python PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}"
- INTERFACE_LINK_LIBRARIES "-undefined dynamic_lookup"
- )
# Need to handle special cases where both debug and release
# libraries are available (in form of debug;A;optimized;B) in PYTHON_LIBRARIES
-elseif(PYTHON_LIBRARY_DEBUG AND PYTHON_LIBRARY_RELEASE)
+if(PYTHON_LIBRARY_DEBUG AND PYTHON_LIBRARY_RELEASE)
set_target_properties(Python::Python PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "$<$<NOT:$<CONFIG:Debug>>:${PYTHON_LIBRARY_RELEASE}>;$<$<CONFIG:Debug>:${PYTHON_LIBRARY_DEBUG}>"
@@ -56,6 +51,35 @@ else()
)
endif()
+# separate target when linking to make an extension module, which should not
+# link explicitly to the python library on Unix-like platforms
+add_library(Python::Module INTERFACE IMPORTED)
+if(WIN32)
+ # identical to Python::Python, cannot be an alias because Python::Python is imported
+ # Need to handle special cases where both debug and release
+ # libraries are available (in form of debug;A;optimized;B) in PYTHON_LIBRARIES
+ if(PYTHON_LIBRARY_DEBUG AND PYTHON_LIBRARY_RELEASE)
+ set_target_properties(Python::Module PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES "$<$<NOT:$<CONFIG:Debug>>:${PYTHON_LIBRARY_RELEASE}>;$<$<CONFIG:Debug>:${PYTHON_LIBRARY_DEBUG}>"
+ )
+ else()
+ set_target_properties(Python::Module PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES "${PYTHON_LIBRARIES}"
+ )
+ endif()
+else()
+ set_target_properties(Python::Module PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}"
+ )
+ if(APPLE)
+ set_target_properties(Python::Module PROPERTIES
+ INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup"
+ )
+ endif(APPLE)
+endif(WIN32)
+
########################################################################
# Check for the existence of a python module: