diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 34b22a57ae..c3b1532bfe 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -543,7 +543,9 @@ source_group( FILES ${PYBIND11_HEADERS}) # Make sure pytest is found or produce a warning -pybind11_find_import(pytest VERSION 3.1) +if(NOT CMAKE_CROSSCOMPILING) + pybind11_find_import(pytest VERSION 3.1) +endif() if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) # This is not used later in the build, so it's okay to regenerate each time. diff --git a/tools/pybind11Common.cmake b/tools/pybind11Common.cmake index 1c1d4f88a3..da887a2253 100644 --- a/tools/pybind11Common.cmake +++ b/tools/pybind11Common.cmake @@ -41,7 +41,18 @@ set(pybind11_INCLUDE_DIRS "${pybind11_INCLUDE_DIR}" CACHE INTERNAL "Include directory for pybind11 (Python not requested)") -if(CMAKE_CROSSCOMPILING AND PYBIND11_USE_CROSSCOMPILING) +# CMP0190 prohibits calling FindPython with both Interpreter and Development components +# when cross-compiling, unless the CMAKE_CROSSCOMPILING_EMULATOR variable is defined. +if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.1") + cmake_policy(GET CMP0190 _pybind11_cmp0190) + if(_pybind11_cmp0190 STREQUAL "NEW") + set(PYBIND11_USE_CROSSCOMPILING "ON") + endif() +endif() + +if(CMAKE_CROSSCOMPILING + AND PYBIND11_USE_CROSSCOMPILING + AND NOT DEFINED CMAKE_CROSSCOMPILING_EMULATOR) set(_PYBIND11_CROSSCOMPILING ON CACHE INTERNAL "") diff --git a/tools/pybind11GuessPythonExtSuffix.cmake b/tools/pybind11GuessPythonExtSuffix.cmake index b8c351ef08..2c30e05d5b 100644 --- a/tools/pybind11GuessPythonExtSuffix.cmake +++ b/tools/pybind11GuessPythonExtSuffix.cmake @@ -14,15 +14,23 @@ function(pybind11_guess_python_module_extension python) STRING "Extension suffix for Python extension modules (Initialized from SETUPTOOLS_EXT_SUFFIX)") endif() + + # The final extension depends on the system + set(_PY_BUILD_EXTENSION "${CMAKE_SHARED_MODULE_SUFFIX}") + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(_PY_BUILD_EXTENSION ".pyd") + endif() + + # If running under scikit-build-core, use the SKBUILD_SOABI variable: + if(NOT DEFINED PYTHON_MODULE_EXT_SUFFIX AND DEFINED SKBUILD_SOABI) + message(STATUS "Determining Python extension suffix based on SKBUILD_SOABI: ${SKBUILD_SOABI}") + set(PYTHON_MODULE_EXT_SUFFIX ".${SKBUILD_SOABI}${_PY_BUILD_EXTENSION}") + endif() + # If that didn't work, use the Python_SOABI variable: if(NOT DEFINED PYTHON_MODULE_EXT_SUFFIX AND DEFINED ${python}_SOABI) message( STATUS "Determining Python extension suffix based on ${python}_SOABI: ${${python}_SOABI}") - # The final extension depends on the system - set(_PY_BUILD_EXTENSION "${CMAKE_SHARED_MODULE_SUFFIX}") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set(_PY_BUILD_EXTENSION ".pyd") - endif() # If the SOABI already has an extension, use it as the full suffix # (used for debug versions of Python on Windows) if(${python}_SOABI MATCHES "\\.") @@ -43,9 +51,9 @@ function(pybind11_guess_python_module_extension python) # If we could not deduce the extension suffix, unset the results: if(NOT DEFINED PYTHON_MODULE_EXT_SUFFIX) - unset(PYTHON_MODULE_DEBUG_POSTFIX PARENT_SCOPE) - unset(PYTHON_MODULE_EXTENSION PARENT_SCOPE) - unset(PYTHON_IS_DEBUG PARENT_SCOPE) + unset(PYTHON_MODULE_DEBUG_POSTFIX CACHE) + unset(PYTHON_MODULE_EXTENSION CACHE) + unset(PYTHON_IS_DEBUG CACHE) return() endif() @@ -75,12 +83,12 @@ function(pybind11_guess_python_module_extension python) # Return results set(PYTHON_MODULE_DEBUG_POSTFIX "${_PYTHON_MODULE_DEBUG_POSTFIX}" - PARENT_SCOPE) + CACHE INTERNAL "") set(PYTHON_MODULE_EXTENSION "${_PYTHON_MODULE_EXTENSION}" - PARENT_SCOPE) + CACHE INTERNAL "") set(PYTHON_IS_DEBUG "${_PYTHON_IS_DEBUG}" - PARENT_SCOPE) + CACHE INTERNAL "") endfunction() diff --git a/tools/pybind11NewTools.cmake b/tools/pybind11NewTools.cmake index e881ca7ca2..5ab3142e47 100644 --- a/tools/pybind11NewTools.cmake +++ b/tools/pybind11NewTools.cmake @@ -106,18 +106,7 @@ if(PYBIND11_MASTER_PROJECT) endif() endif() -if(NOT _PYBIND11_CROSSCOMPILING) - # If a user finds Python, they may forget to include the Interpreter component - # and the following two steps require it. It is highly recommended by CMake - # when finding development libraries anyway, so we will require it. - if(NOT DEFINED ${_Python}_EXECUTABLE) - message( - FATAL_ERROR - "${_Python} was found without the Interpreter component. Pybind11 requires this component." - ) - - endif() - +if(NOT _PYBIND11_CROSSCOMPILING AND DEFINED ${_Python}_EXECUTABLE) if(DEFINED PYBIND11_PYTHON_EXECUTABLE_LAST AND NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST) # Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed @@ -190,15 +179,15 @@ else() include("${CMAKE_CURRENT_LIST_DIR}/pybind11GuessPythonExtSuffix.cmake") pybind11_guess_python_module_extension("${_Python}") endif() - # When cross-compiling, we cannot query the Python interpreter, so we require - # the user to set these variables explicitly. if(NOT DEFINED PYTHON_IS_DEBUG OR NOT DEFINED PYTHON_MODULE_EXTENSION OR NOT DEFINED PYTHON_MODULE_DEBUG_POSTFIX) message( FATAL_ERROR - "When cross-compiling, you should set the PYTHON_IS_DEBUG, PYTHON_MODULE_EXTENSION and PYTHON_MODULE_DEBUG_POSTFIX \ - variables appropriately before loading pybind11 (e.g. in your CMake toolchain file)") + "A Python interpreter was not found, or you are cross-compiling, and the " + "PYTHON_IS_DEBUG, PYTHON_MODULE_EXTENSION and PYTHON_MODULE_DEBUG_POSTFIX " + "variables could not be guessed. Set these variables appropriately before " + "loading pybind11 (e.g. in your CMake toolchain file)") endif() endif() @@ -248,10 +237,7 @@ if(TARGET ${_Python}::Module) # files. get_target_property(module_target_type ${_Python}::Module TYPE) if(ANDROID AND module_target_type STREQUAL INTERFACE_LIBRARY) - set_property( - TARGET ${_Python}::Module - APPEND - PROPERTY INTERFACE_LINK_LIBRARIES "${${_Python}_LIBRARIES}") + target_link_libraries(${_Python}::Module INTERFACE ${${_Python}_LIBRARIES}) endif() set_property( diff --git a/tools/test-pybind11GuessPythonExtSuffix.cmake b/tools/test-pybind11GuessPythonExtSuffix.cmake index a66282db26..244db8891c 100644 --- a/tools/test-pybind11GuessPythonExtSuffix.cmake +++ b/tools/test-pybind11GuessPythonExtSuffix.cmake @@ -87,6 +87,30 @@ unset(PYTHON_MODULE_EXT_SUFFIX) unset(PYTHON_MODULE_EXT_SUFFIX CACHE) unset(ENV{SETUPTOOLS_EXT_SUFFIX}) +# Check the priority of the possible suffix sources. +set(ENV{SETUPTOOLS_EXT_SUFFIX} ".from-setuptools.pyd") +set(SKBUILD_SOABI "from-skbuild") +set(Python3_SOABI "from-python3") +pybind11_guess_python_module_extension("Python3") +expect_streq("${PYTHON_MODULE_EXTENSION}" ".from-setuptools.pyd") + +unset(PYTHON_MODULE_EXT_SUFFIX CACHE) +unset(ENV{SETUPTOOLS_EXT_SUFFIX}) +pybind11_guess_python_module_extension("Python3") +expect_streq("${PYTHON_MODULE_EXTENSION}" ".from-skbuild.pyd") + +unset(SKBUILD_SOABI) +pybind11_guess_python_module_extension("Python3") +expect_streq("${PYTHON_MODULE_EXTENSION}" ".from-python3.pyd") + +set(Python3_SOABI "") +pybind11_guess_python_module_extension("Python3") +expect_streq("${PYTHON_MODULE_EXTENSION}" ".pyd") + +unset(Python3_SOABI) +pybind11_guess_python_module_extension("Python3") +expect_streq("${PYTHON_MODULE_EXTENSION}" "") + # macOS set(CMAKE_SYSTEM_NAME "Darwin") set(CMAKE_SHARED_MODULE_SUFFIX ".so")