From 9b0510fa57ccace72de1147e0908c033e37b4fb1 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Sun, 5 Jan 2025 17:27:42 +0100 Subject: [PATCH] FindPython: add support for multiple searches in same directory In some situations, like cross-compilation, it can be required to search for the host python interpreter as well as the cross-compilation development artifacts. By managing different prefixes for the artifacts, multiple and independent searches can be achieved. --- .../dev/FindPython-ARTIFACTS-PREFIX.rst | 7 + Modules/FindPython.cmake | 113 ++++++---- Modules/FindPython/Support.cmake | 212 +++++++++--------- Modules/FindPython2.cmake | 44 +++- Modules/FindPython3.cmake | 44 +++- .../FindPython/ArtifactsPrefix/CMakeLists.txt | 24 ++ Tests/FindPython/CMakeLists.txt | 15 ++ Tests/FindPython/Python/CMakeLists.txt | 40 ++++ Tests/FindPython/Python2/CMakeLists.txt | 41 ++++ Tests/FindPython/Python3/CMakeLists.txt | 41 ++++ Tests/FindPython/TEST_spam.c | 41 ++++ 11 files changed, 468 insertions(+), 154 deletions(-) create mode 100644 Help/release/dev/FindPython-ARTIFACTS-PREFIX.rst create mode 100644 Tests/FindPython/ArtifactsPrefix/CMakeLists.txt create mode 100644 Tests/FindPython/TEST_spam.c diff --git a/Help/release/dev/FindPython-ARTIFACTS-PREFIX.rst b/Help/release/dev/FindPython-ARTIFACTS-PREFIX.rst new file mode 100644 index 0000000000..4b3e6e5dbf --- /dev/null +++ b/Help/release/dev/FindPython-ARTIFACTS-PREFIX.rst @@ -0,0 +1,7 @@ +FindPython-ARTIFACTS-PREFIX +--------------------------- + +* The :module:`FindPython`, :module:`FindPython2`, and :module:`FindPython3` + modules gained the possibility to do multiple calls in the same directory by + using, respectively, the variables ``Python_ARTIFACTS_PREFIX``, + ``Python2_ARTIFACTS_PREFIX``, and ``Python3_ARTIFACTS_PREFIX``. diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 31ed614952..5c1e1ed6ba 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -559,6 +559,31 @@ can be controlled with the following variable: * If set to ``FALSE`` or undefined: Enable multiple version/component requirements. +``Python_ARTIFACTS_PREFIX`` + .. versionadded:: 3.32 + + Define a custom prefix which will be used for the definition of all the + result variables, targets, and commands. By using this variable, this module + supports multiple calls in the same directory with different + version/component requirements. + For example, in case of cross-compilation, development components are needed + but the native python interpreter can also be required: + + .. code-block:: cmake + + find_package(Python COMPONENTS Development) + + set(Python_ARTIFACTS_PREFIX "_HOST") + find_package(Python COMPONENTS Interpreter) + + # Here Python_HOST_EXECUTABLE and Python_HOST::Interpreter artifacts are defined + + .. note:: + + For consistency with standard behavior of modules, the various standard + ``_FOUND`` variables (i.e. without the custom prefix) are also defined by + each call to the :command:`find_package` command. + Commands ^^^^^^^^ @@ -600,78 +625,86 @@ If the library type is not specified, ``MODULE`` is assumed. cmake_policy(PUSH) # numbers and boolean constants cmake_policy (SET CMP0012 NEW) +# foreach loop variable scope +cmake_policy (SET CMP0124 NEW) -set (_PYTHON_PREFIX Python) -unset (_Python_REQUIRED_VERSION_MAJOR) -unset (_Python_REQUIRED_VERSIONS) +set (_PYTHON_BASE Python) +if(${_PYTHON_BASE}_ARTIFACTS_PREFIX) + set(_PYTHON_PREFIX "${_PYTHON_BASE}${${_PYTHON_BASE}_ARTIFACTS_PREFIX}") +else() + set(_PYTHON_PREFIX "${_PYTHON_BASE}") +endif() + +unset (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) +unset (_${_PYTHON_PREFIX}_REQUIRED_VERSIONS) if (Python_FIND_VERSION_RANGE) # compute list of major versions - foreach (_Python_MAJOR IN ITEMS 3 2) - if (_Python_MAJOR VERSION_GREATER_EQUAL Python_FIND_VERSION_MIN_MAJOR - AND ((Python_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND _Python_MAJOR VERSION_LESS_EQUAL Python_FIND_VERSION_MAX) - OR (Python_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND _Python_MAJOR VERSION_LESS Python_FIND_VERSION_MAX))) - list (APPEND _Python_REQUIRED_VERSIONS ${_Python_MAJOR}) + foreach (version_major IN ITEMS 3 2) + if (version_major VERSION_GREATER_EQUAL Python_FIND_VERSION_MIN_MAJOR + AND ((Python_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND version_major VERSION_LESS_EQUAL Python_FIND_VERSION_MAX) + OR (Python_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND version_major VERSION_LESS Python_FIND_VERSION_MAX))) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VERSIONS ${version_major}) endif() endforeach() - list (LENGTH _Python_REQUIRED_VERSIONS _Python_VERSION_COUNT) - if (_Python_VERSION_COUNT EQUAL 0) - unset (_Python_REQUIRED_VERSIONS) - elseif (_Python_VERSION_COUNT EQUAL 1) - set (_Python_REQUIRED_VERSION_MAJOR ${_Python_REQUIRED_VERSIONS}) + list (LENGTH _${_PYTHON_PREFIX}_REQUIRED_VERSIONS _${_PYTHON_PREFIX}_VERSION_COUNT) + if (_${_PYTHON_PREFIX}_VERSION_COUNT EQUAL 0) + unset (_${_PYTHON_PREFIX}_REQUIRED_VERSIONS) + elseif (_${_PYTHON_PREFIX}_VERSION_COUNT EQUAL 1) + set (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR ${_${_PYTHON_PREFIX}_REQUIRED_VERSIONS}) endif() elseif (DEFINED Python_FIND_VERSION) - set (_Python_REQUIRED_VERSION_MAJOR ${Python_FIND_VERSION_MAJOR}) + set (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR ${Python_FIND_VERSION_MAJOR}) else() - set (_Python_REQUIRED_VERSIONS 3 2) + set (_${_PYTHON_PREFIX}_REQUIRED_VERSIONS 3 2) endif() -if (_Python_REQUIRED_VERSION_MAJOR) +if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) -elseif (_Python_REQUIRED_VERSIONS) +elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSIONS) # iterate over versions in quiet and NOT required modes to avoid multiple # "Found" messages and prematurally failure. - set (_Python_QUIETLY ${Python_FIND_QUIETLY}) - set (_Python_REQUIRED ${Python_FIND_REQUIRED}) + set (_${_PYTHON_PREFIX}_QUIETLY ${Python_FIND_QUIETLY}) + set (_${_PYTHON_PREFIX}_REQUIRED ${Python_FIND_REQUIRED}) set (Python_FIND_QUIETLY TRUE) set (Python_FIND_REQUIRED FALSE) - set (_Python_REQUIRED_VERSION_LAST 2) + set (_${_PYTHON_PREFIX}_REQUIRED_VERSION_LAST 2) - unset (_Python_INPUT_VARS) - foreach (_Python_ITEM IN ITEMS Python_EXECUTABLE Python_COMPILER Python_LIBRARY - Python_INCLUDE_DIR Python_NumPy_INCLUDE_DIR) - if (NOT DEFINED ${_Python_ITEM}) - list (APPEND _Python_INPUT_VARS ${_Python_ITEM}) + unset (_${_PYTHON_PREFIX}_INPUT_VARS) + foreach (item IN ITEMS Python_EXECUTABLE Python_COMPILER Python_LIBRARY + Python_INCLUDE_DIR Python_NumPy_INCLUDE_DIR) + if (NOT DEFINED ${item}) + list (APPEND _${_PYTHON_PREFIX}_INPUT_VARS ${item}) endif() endforeach() - foreach (_Python_REQUIRED_VERSION_MAJOR IN LISTS _Python_REQUIRED_VERSIONS) - set (Python_FIND_VERSION ${_Python_REQUIRED_VERSION_MAJOR}) + foreach (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR IN LISTS _${_PYTHON_PREFIX}_REQUIRED_VERSIONS) + set (Python_FIND_VERSION ${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}) include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) if (Python_FOUND OR - _Python_REQUIRED_VERSION_MAJOR EQUAL _Python_REQUIRED_VERSION_LAST) + _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_LAST) break() endif() # clean-up INPUT variables not set by the user - foreach (_Python_ITEM IN LISTS _Python_INPUT_VARS) - unset (${_Python_ITEM}) + foreach (item IN LISTS _${_PYTHON_PREFIX}_INPUT_VARS) + unset (${item}) endforeach() # clean-up some CACHE variables to ensure look-up restart from scratch - foreach (_Python_ITEM IN LISTS _Python_CACHED_VARS) - unset (${_Python_ITEM} CACHE) + foreach (item IN LISTS _${_PYTHON_PREFIX}_CACHED_VARS) + unset (${item} CACHE) endforeach() endforeach() unset (Python_FIND_VERSION) - set (Python_FIND_QUIETLY ${_Python_QUIETLY}) - set (Python_FIND_REQUIRED ${_Python_REQUIRED}) + set (Python_FIND_QUIETLY ${_${_PYTHON_PREFIX}_QUIETLY}) + set (Python_FIND_REQUIRED ${_${_PYTHON_PREFIX}_REQUIRED}) if (Python_FIND_REQUIRED OR NOT Python_FIND_QUIETLY) # call again validation command to get "Found" or error message find_package_handle_standard_args (Python HANDLE_COMPONENTS HANDLE_VERSION_RANGE - REQUIRED_VARS ${_Python_REQUIRED_VARS} + REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} VERSION_VAR Python_VERSION) endif() else() @@ -687,12 +720,14 @@ else() REASON_FAILURE_MESSAGE "Version range specified \"${Python_FIND_VERSION_RANGE}\" does not include supported versions") endif() -if (COMMAND __Python_add_library) - macro (Python_add_library) - __Python_add_library (Python ${ARGV}) - endmacro() +if (COMMAND __${_PYTHON_PREFIX}_add_library AND NOT COMMAND ${_PYTHON_PREFIX}_add_library) + cmake_language(EVAL CODE + "macro (${_PYTHON_PREFIX}_add_library) + __${_PYTHON_PREFIX}_add_library (${_PYTHON_PREFIX} \${ARGV}) + endmacro()") endif() +unset (_PYTHON_BASE) unset (_PYTHON_PREFIX) cmake_policy(POP) diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index d103e82c6d..7bfdd88b57 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -45,10 +45,10 @@ include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake) # helper commands # macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) + if (${_PYTHON_BASE}_FIND_REQUIRED) message (FATAL_ERROR "${_PYTHON_MSG}") else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) + if (NOT ${_PYTHON_BASE}_FIND_QUIETLY) message(STATUS "${_PYTHON_MSG}") endif () endif() @@ -532,7 +532,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) endif() endif() - if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND _${_PYTHON_PREFIX}_EXECUTABLE + if ("Interpreter" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND _${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING) if (NAME STREQUAL "PREFIX") execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))" @@ -1003,9 +1003,9 @@ function (_PYTHON_VALIDATE_INTERPRETER) endif() endif() - if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS + OR "Development.SABIModule" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS + OR "Development.Embed" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) AND NOT CMAKE_CROSSCOMPILING) # In this case, interpreter must have same architecture as environment execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c @@ -1371,7 +1371,7 @@ endfunction() function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module) - if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if ("Development.${module}" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) if (module STREQUAL "SABIModule" AND "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_LESS "3.2") # Stable API was introduced in version 3.2 @@ -1401,23 +1401,23 @@ function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module) endfunction() -if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) +if (${_PYTHON_BASE}_FIND_VERSION_RANGE) # range must include internal major version - if (${_PYTHON_PREFIX}_FIND_VERSION_MIN_MAJOR VERSION_GREATER _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR - OR ((${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" - AND ${_PYTHON_PREFIX}_FIND_VERSION_MAX VERSION_LESS _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - OR (${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" - AND ${_PYTHON_PREFIX}_FIND_VERSION_MAX VERSION_LESS_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR))) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong version range specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_RANGE}\", but expected version range must include major version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") + if (${_PYTHON_BASE}_FIND_VERSION_MIN_MAJOR VERSION_GREATER _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR + OR ((${_PYTHON_BASE}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" + AND ${_PYTHON_BASE}_FIND_VERSION_MAX VERSION_LESS _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + OR (${_PYTHON_BASE}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" + AND ${_PYTHON_BASE}_FIND_VERSION_MAX VERSION_LESS_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR))) + _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong version range specified is \"${${_PYTHON_BASE}_FIND_VERSION_RANGE}\", but expected version range must include major version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") cmake_policy(POP) return() endif() else() - if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + if (DEFINED ${_PYTHON_BASE}_FIND_VERSION_MAJOR + AND NOT ${_PYTHON_BASE}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) # If major version is specified, it must be the same as internal major version - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") + _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_BASE}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") cmake_policy(POP) return() @@ -1426,42 +1426,42 @@ endif() # handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) +if (NOT ${_PYTHON_BASE}_FIND_COMPONENTS) + set (${_PYTHON_BASE}_FIND_COMPONENTS Interpreter) + set (${_PYTHON_BASE}_FIND_REQUIRED_Interpreter TRUE) endif() -if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development.Module") +if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) + list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Interpreter" "Development.Module") endif() -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed") +if ("Development" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) + list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Development.Module" "Development.Embed") endif() -list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS) -foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.SABIModule Development.Embed NumPy) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) +list (REMOVE_DUPLICATES ${_PYTHON_BASE}_FIND_COMPONENTS) +foreach (component IN ITEMS Interpreter Compiler Development Development.Module Development.SABIModule Development.Embed NumPy) + set (${_PYTHON_PREFIX}_${component}_FOUND FALSE) endforeach() -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module TRUE) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed TRUE) +if (${_PYTHON_BASE}_FIND_REQUIRED_Development) + set (${_PYTHON_BASE}_FIND_REQUIRED_Development.Module TRUE) + set (${_PYTHON_BASE}_FIND_REQUIRED_Development.Embed TRUE) endif() unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS) unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS) -if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) +if ("Development.Module" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY") endif() list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR") endif() -if ("Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) +if ("Development.SABIModule" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "SABI_LIBRARY") endif() list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "INCLUDE_DIR") endif() -if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) +if ("Development.Embed" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR") endif() set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS}) @@ -1472,29 +1472,29 @@ list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) unset (_${_PYTHON_PREFIX}_FIND_VERSION_EXACT) -if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) +if (${_PYTHON_BASE}_FIND_VERSION_RANGE) unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if ((${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" - AND _${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION_MIN) - AND ((${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" - AND _${_PYTHON_PREFIX}_VERSION VERSION_LESS_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION_MAX) - OR (${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" - AND _${_PYTHON_PREFIX}_VERSION VERSION_LESS ${_PYTHON_PREFIX}_FIND_VERSION_MAX))) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) + foreach (version IN LISTS _${_PYTHON_PREFIX}_VERSIONS) + if ((${_PYTHON_BASE}_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" + AND version VERSION_GREATER_EQUAL ${_PYTHON_BASE}_FIND_VERSION_MIN) + AND ((${_PYTHON_BASE}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" + AND version VERSION_LESS_EQUAL ${_PYTHON_BASE}_FIND_VERSION_MAX) + OR (${_PYTHON_BASE}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" + AND version VERSION_LESS ${_PYTHON_BASE}_FIND_VERSION_MAX))) + list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${version}) endif() endforeach() else() - if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) + if (${_PYTHON_BASE}_FIND_VERSION_COUNT GREATER 1) + if (${_PYTHON_BASE}_FIND_VERSION_EXACT) set (_${_PYTHON_PREFIX}_FIND_VERSION_EXACT "EXACT") - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) + set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_BASE}_FIND_VERSION_MAJOR}.${${_PYTHON_BASE}_FIND_VERSION_MINOR}) else() unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL "${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}") - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) + foreach (version IN LISTS _${_PYTHON_PREFIX}_VERSIONS) + if (version VERSION_GREATER_EQUAL "${${_PYTHON_BASE}_FIND_VERSION_MAJOR}.${${_PYTHON_BASE}_FIND_VERSION_MINOR}") + list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${version}) endif() endforeach() endif() @@ -1553,9 +1553,9 @@ endif() unset (_${_PYTHON_PREFIX}_REGISTRY_VIEW) if (CMAKE_SIZEOF_VOID_P) math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if ("Development.Module" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS + OR "Development.SABIModule" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS + OR "Development.Embed" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) # In this case, search only for 64bit or 32bit set (_${_PYTHON_PREFIX}_REGISTRY_VIEW REGISTRY_VIEW ${_${_PYTHON_PREFIX}_ARCH}) if (WIN32 AND (NOT CMAKE_GENERATOR_PLATFORM AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM" @@ -1772,7 +1772,7 @@ if (CMAKE_HOST_WIN32) endif() function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module) - if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if ("Development.${module}" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) string (TOUPPER "${module}" id) set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:") if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) @@ -1787,12 +1787,12 @@ function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module) string (MD5 signature "${signature}") if (signature STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE) if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_library (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_EXACT) + _python_validate_library (VERSION ${${_PYTHON_BASE}_FIND_VERSION} EXACT CHECK_EXISTS) + elseif (${_PYTHON_BASE}_FIND_VERSION_RANGE) _python_validate_library (IN_RANGE CHECK_EXISTS) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_library (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + elseif (DEFINED ${_PYTHON_BASE}_FIND_VERSION) + _python_validate_library (VERSION ${${_PYTHON_BASE}_FIND_VERSION} CHECK_EXISTS) else() _python_validate_library (CHECK_EXISTS) endif() @@ -1801,12 +1801,12 @@ function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module) _python_validate_sabi_library (CHECK_EXISTS) endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_include_dir (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_EXACT) + _python_validate_include_dir (VERSION ${${_PYTHON_BASE}_FIND_VERSION} EXACT CHECK_EXISTS) + elseif (${_PYTHON_BASE}_FIND_VERSION_RANGE) _python_validate_include_dir (IN_RANGE CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_include_dir (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + elseif (${_PYTHON_BASE}_FIND_VERSION) + _python_validate_include_dir (VERSION ${${_PYTHON_BASE}_FIND_VERSION} CHECK_EXISTS) else() _python_validate_include_dir (CHECK_EXISTS) endif() @@ -1882,11 +1882,11 @@ endif() # first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) +if ("Interpreter" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE _${_PYTHON_PREFIX}_EXECUTABLE_DEBUG _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) + if (${_PYTHON_BASE}_FIND_REQUIRED_Interpreter) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) endif() @@ -1903,12 +1903,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}") if (__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE) # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_interpreter (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_EXACT) + _python_validate_interpreter (VERSION ${${_PYTHON_BASE}_FIND_VERSION} EXACT CHECK_EXISTS) + elseif (${_PYTHON_BASE}_FIND_VERSION_RANGE) _python_validate_interpreter (IN_RANGE CHECK_EXISTS) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_interpreter (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + elseif (DEFINED ${_PYTHON_BASE}_FIND_VERSION) + _python_validate_interpreter (VERSION ${${_PYTHON_BASE}_FIND_VERSION} CHECK_EXISTS) else() _python_validate_interpreter (CHECK_EXISTS) endif() @@ -1936,10 +1936,10 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}) set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_RANGE) list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${${_PYTHON_PREFIX}_FIND_VERSION}) + elseif (DEFINED ${_PYTHON_BASE}_FIND_VERSION) + list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${${_PYTHON_BASE}_FIND_VERSION}) endif() while (TRUE) @@ -2053,7 +2053,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) else() # look-up for various versions and locations set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_RANGE) list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE) endif() @@ -2383,9 +2383,9 @@ endif() # second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) +if ("Compiler" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) + if (${_PYTHON_BASE}_FIND_REQUIRED_Compiler) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) endif() @@ -2400,12 +2400,12 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}") if (__${_PYTHON_PREFIX}_COMPILER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_COMPILER_SIGNATURE) # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_compiler (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_EXACT) + _python_validate_compiler (VERSION ${${_PYTHON_BASE}_FIND_VERSION} EXACT CHECK_EXISTS) + elseif (${_PYTHON_BASE}_FIND_VERSION_RANGE) _python_validate_compiler (IN_RANGE CHECK_EXISTS) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_compiler (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + elseif (DEFINED ${_PYTHON_BASE}_FIND_VERSION) + _python_validate_compiler (VERSION ${${_PYTHON_BASE}_FIND_VERSION} CHECK_EXISTS) else() _python_validate_compiler (CHECK_EXISTS) endif() @@ -2443,10 +2443,10 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}) set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_RANGE) list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${${_PYTHON_PREFIX}_FIND_VERSION}) + elseif (DEFINED ${_PYTHON_BASE}_FIND_VERSION) + list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${${_PYTHON_BASE}_FIND_VERSION}) endif() while (TRUE) @@ -2541,7 +2541,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) else() # try using root dir and registry set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) + if (${_PYTHON_BASE}_FIND_VERSION_RANGE) list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE) endif() @@ -2553,7 +2553,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSION} + VERSION ${_${_PYTHON_PREFIX}_VERSION} COMPILER) _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS @@ -2737,7 +2737,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() # third step, search for the development artifacts -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module) +if (${_PYTHON_BASE}_FIND_REQUIRED_Development.Module) if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES) endif() @@ -2745,7 +2745,7 @@ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS) endif() endif() -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.SABIModule) +if (${_PYTHON_BASE}_FIND_REQUIRED_Development.SABIModule) if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_SABI_LIBRARIES) endif() @@ -2753,7 +2753,7 @@ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.SABIModule) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS) endif() endif() -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed) +if (${_PYTHON_BASE}_FIND_REQUIRED_Development.Embed) if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES) endif() @@ -2763,9 +2763,9 @@ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed) endif() list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS) ## Development environment is not compatible with IronPython interpreter -if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) +if (("Development.Module" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS + OR "Development.SABIModule" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS + OR "Development.Embed" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) AND ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") OR NOT ${_PYTHON_PREFIX}_Interpreter_FOUND)) @@ -3610,11 +3610,11 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS set (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED FALSE) foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Module SABIModule Embed) string (TOUPPER "${_${_PYTHON_PREFIX}_COMPONENT}" _${_PYTHON_PREFIX}_ID) - if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND "LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${_${_PYTHON_PREFIX}_ID}_ARTIFACTS) set (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED TRUE) endif() - if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND "SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${_${_PYTHON_PREFIX}_ID}_ARTIFACTS) set (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED TRUE) endif() @@ -3876,7 +3876,7 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() - if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + if ("Development" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Development.Module_FOUND AND ${_PYTHON_PREFIX}_Development.Embed_FOUND) set (${_PYTHON_PREFIX}_Development_FOUND TRUE) @@ -3963,10 +3963,10 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _${_PYTHON_PREFIX}_DEVELOPMENT_EMBED_SIGNATURE) endif() -if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy) +if (${_PYTHON_BASE}_FIND_REQUIRED_NumPy) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS) endif() -if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND) +if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND) list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) if (DEFINED ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR @@ -4079,16 +4079,22 @@ foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development endif() endforeach() -find_package_handle_standard_args (${_PYTHON_PREFIX} +foreach (component IN ITEMS Interpreter Compiler Development Development.Module Development.SABIModule Development.Embed NumPy) + set(${_PYTHON_BASE}_${component}_FOUND ${${_PYTHON_PREFIX}_${component}_FOUND}) +endforeach() + +find_package_handle_standard_args (${_PYTHON_BASE} REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} VERSION_VAR ${_PYTHON_PREFIX}_VERSION HANDLE_VERSION_RANGE HANDLE_COMPONENTS REASON_FAILURE_MESSAGE "${_${_PYTHON_PREFIX}_REASON_FAILURE}") +set(${_PYTHON_PREFIX}_FOUND ${${_PYTHON_BASE}_FOUND}) + # Create imported targets and helper functions if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") - if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + if ("Interpreter" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND) if(NOT TARGET ${_PYTHON_PREFIX}::Interpreter) add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) @@ -4112,7 +4118,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") endif() endif() - if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + if ("Compiler" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Compiler_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) @@ -4120,11 +4126,11 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") endif() - if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + if (("Development.Module" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Development.Module_FOUND) - OR ("Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + OR ("Development.SABIModule" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Development.SABIModule_FOUND) - OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + OR ("Development.Embed" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)) macro (__PYTHON_IMPORT_LIBRARY __name) @@ -4362,7 +4368,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") endfunction() endif() - if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_NumPy_FOUND + if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_NumPy_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND TARGET ${_PYTHON_PREFIX}::Module) add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED) set_property (TARGET ${_PYTHON_PREFIX}::NumPy diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 860144db06..0b682fd867 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -440,6 +440,31 @@ can be controlled with the following variable: * If set to ``FALSE`` or undefined: Enable multiple version/component requirements. +``Python2_ARTIFACTS_PREFIX`` + .. versionadded:: 3.32 + + Define a custom prefix which will be used for the definition of all the + result variables, targets, and commands. By using this variable, this module + supports multiple calls in the same directory with different + version/component requirements. + For example, in case of cross-compilation, development components are needed + but the native python interpreter can also be required: + + .. code-block:: cmake + + find_package(Python2 COMPONENTS Development) + + set(Python2_ARTIFACTS_PREFIX "_HOST") + find_package(Python2 COMPONENTS Interpreter) + + # Here Python2_HOST_EXECUTABLE and Python2_HOST::Interpreter artifacts are defined + + .. note:: + + For consistency with standard behavior of modules, the various standard + ``_FOUND`` variables (i.e. without the custom prefix) are also defined by + each call to the :command:`find_package` command. + Commands ^^^^^^^^ @@ -460,16 +485,23 @@ If library type is not specified, ``MODULE`` is assumed. #]=======================================================================] -set (_PYTHON_PREFIX Python2) +set (_PYTHON_BASE Python2) +if(${_PYTHON_BASE}_ARTIFACTS_PREFIX) + set(_PYTHON_PREFIX "${_PYTHON_BASE}${${_PYTHON_BASE}_ARTIFACTS_PREFIX}") +else() + set(_PYTHON_PREFIX "${_PYTHON_BASE}") +endif() -set (_Python2_REQUIRED_VERSION_MAJOR 2) +set (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR 2) include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) -if (COMMAND __Python2_add_library) - macro (Python2_add_library) - __Python2_add_library (Python2 ${ARGV}) - endmacro() +if (COMMAND __${_PYTHON_PREFIX}_add_library AND NOT COMMAND ${_PYTHON_PREFIX}_add_library) + cmake_language(EVAL CODE + "macro (${_PYTHON_PREFIX}_add_library) + __${_PYTHON_PREFIX}_add_library (${_PYTHON_PREFIX} \${ARGV}) + endmacro()") endif() +unset (_PYTHON_BASE) unset (_PYTHON_PREFIX) diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 88a0f9c5f5..2b2d25372d 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -557,6 +557,31 @@ can be controlled with the following variable: * If set to ``FALSE`` or undefined: Enable multiple version/component requirements. +``Python3_ARTIFACTS_PREFIX`` + .. versionadded:: 3.32 + + Define a custom prefix which will be used for the definition of all the + result variables, targets, and commands. By using this variable, this module + supports multiple calls in the same directory with different + version/component requirements. + For example, in case of cross-compilation, development components are needed + but the native python interpreter can also be required: + + .. code-block:: cmake + + find_package(Python3 COMPONENTS Development) + + set(Python3_ARTIFACTS_PREFIX "_HOST") + find_package(Python3 COMPONENTS Interpreter) + + # Here Python3_HOST_EXECUTABLE and Python3_HOST::Interpreter artifacts are defined + + .. note:: + + For consistency with standard behavior of modules, the various standard + ``_FOUND`` variables (i.e. without the custom prefix) are also defined by + each call to the :command:`find_package` command. + Commands ^^^^^^^^ @@ -595,16 +620,23 @@ If the library type is not specified, ``MODULE`` is assumed. #]=======================================================================] -set (_PYTHON_PREFIX Python3) +set (_PYTHON_BASE Python3) +if(${_PYTHON_BASE}_ARTIFACTS_PREFIX) + set(_PYTHON_PREFIX "${_PYTHON_BASE}${${_PYTHON_BASE}_ARTIFACTS_PREFIX}") +else() + set(_PYTHON_PREFIX "${_PYTHON_BASE}") +endif() -set (_Python3_REQUIRED_VERSION_MAJOR 3) +set (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR 3) include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() +if (COMMAND __${_PYTHON_PREFIX}_add_library AND NOT COMMAND ${_PYTHON_PREFIX}_add_library) + cmake_language(EVAL CODE + "macro (${_PYTHON_PREFIX}_add_library) + __${_PYTHON_PREFIX}_add_library (${_PYTHON_PREFIX} \${ARGV}) + endmacro()") endif() +unset (_PYTHON_BASE) unset (_PYTHON_PREFIX) diff --git a/Tests/FindPython/ArtifactsPrefix/CMakeLists.txt b/Tests/FindPython/ArtifactsPrefix/CMakeLists.txt new file mode 100644 index 0000000000..d007017667 --- /dev/null +++ b/Tests/FindPython/ArtifactsPrefix/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.31) + +project(TestArtifactsPrefix C) + +set(Python_ARTIFACTS_PREFIX "_V2") +find_package (Python 2 EXACT REQUIRED) + +if(NOT Python_V2_FOUND OR NOT Python_FOUND) + message(FATAL_ERROR "Python v2 interpreter not found.") +endif() +if(NOT Python_V2_VERSION_MAJOR VERSION_EQUAL 2) + message(FATAL_ERROR "Python v2 interpreter: wrong major version.") +endif() + + +set(Python_ARTIFACTS_PREFIX "_V3") +find_package (Python 3 EXACT REQUIRED) + +if(NOT Python_V3_FOUND OR NOT Python_FOUND) + message(FATAL_ERROR "Python v3 interpreter not found.") +endif() +if(NOT Python_V3_VERSION_MAJOR VERSION_EQUAL 3) + message(FATAL_ERROR "Python v3 interpreter: wrong major version.") +endif() diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt index 7a3b7f7490..f275013f97 100644 --- a/Tests/FindPython/CMakeLists.txt +++ b/Tests/FindPython/CMakeLists.txt @@ -523,6 +523,21 @@ if(CMake_TEST_FindPython2 OR CMake_TEST_FindPython3) APPEND PROPERTY LABELS Python2 Python3) endif() +if(CMake_TEST_FindPython2 AND CMake_TEST_FindPython3) + add_test(NAME FindPython.ArtifactsPrefix COMMAND + ${CMAKE_CTEST_COMMAND} -C $ + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/ArtifactsPrefix" + "${CMake_BINARY_DIR}/Tests/FindPython/ArtifactsPrefix" + ${build_generator_args} + --build-project TestArtifactsPrefix + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $ + ) + + set_property(TEST FindPython.ArtifactsPrefix + APPEND PROPERTY LABELS Python2 Python3) +endif() if(CMake_TEST_FindPython2_SABIModule) add_test(NAME FindPython.Python2.Development.SABIModule COMMAND diff --git a/Tests/FindPython/Python/CMakeLists.txt b/Tests/FindPython/Python/CMakeLists.txt index 70746494ff..187a2e2911 100644 --- a/Tests/FindPython/Python/CMakeLists.txt +++ b/Tests/FindPython/Python/CMakeLists.txt @@ -38,3 +38,43 @@ else() COMMAND "${CMAKE_COMMAND}" -DPYTHON_PACKAGE_NAME=Python -P "${CMAKE_CURRENT_LIST_DIR}/../FindPythonScript.cmake") endif() + + +# +# New search with user's prefix +# +foreach(item IN ITEMS FOUND Development_FOUND Development.Module_FOUND Development.Embed_FOUND) + unset(Python_${item}) +endforeach() + +set(Python_ARTIFACTS_PREFIX "_TEST") +find_package(Python ${Python_REQUESTED_VERSION} REQUIRED COMPONENTS Interpreter Development) +if (NOT Python_TEST_FOUND OR NOT Python_FOUND) + message (FATAL_ERROR "Failed to find Python ${Python_REQUESTED_VERSION} (TEST prefix)") +endif() +if (NOT Python_TEST_Development.Module_FOUND OR NOT Python_Development.Module_FOUND) + message (FATAL_ERROR "Failed to find Python ${Python_REQUESTED_VERSION}, COMPONENT 'Development.Module' (TEST prefix)") +endif() +if (NOT Python_TEST_Development.Embed_FOUND OR NOT Python_Development.Embed_FOUND) + message (FATAL_ERROR "Failed to find Python ${Python_REQUESTED_VERSION}, COMPOENENT 'Development.Embed' (TEST prefix)") +endif() + +if(NOT TARGET Python_TEST::Interpreter) + message(SEND_ERROR "Python_TEST::Interpreter not found") +endif() + +if(NOT TARGET Python_TEST::Python) + message(SEND_ERROR "Python_TEST::Python not found") +endif() +if(NOT TARGET Python_TEST::Module) + message(SEND_ERROR "Python_TEST::Module not found") +endif() + +if (Python_REQUESTED_VERSION) + Python_TEST_add_library (TEST_spam${Python_REQUESTED_VERSION} MODULE ../TEST_spam.c) + target_compile_definitions (TEST_spam${Python_REQUESTED_VERSION} PRIVATE PYTHON${Python_REQUESTED_VERSION}) + + add_test (NAME python_TEST_spam${Python_REQUESTED_VERSION} + COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$" + "${Python_INTERPRETER}" -c "import TEST_spam${Python_REQUESTED_VERSION}; TEST_spam${Python_REQUESTED_VERSION}.system(\"cd\")") +endif() diff --git a/Tests/FindPython/Python2/CMakeLists.txt b/Tests/FindPython/Python2/CMakeLists.txt index f858574200..ffbb140475 100644 --- a/Tests/FindPython/Python2/CMakeLists.txt +++ b/Tests/FindPython/Python2/CMakeLists.txt @@ -45,3 +45,44 @@ add_test(NAME findpython2_script COMMAND "${CMAKE_COMMAND}" -DPYTHON_PACKAGE_NAME=Python2 -DPython2_FIND_STRATEGY=${Python2_FIND_STRATEGY} -P "${CMAKE_CURRENT_LIST_DIR}/../FindPythonScript.cmake") + + +# +# New search with user's prefix +# +foreach(item IN ITEMS FOUND Development_FOUND Development.Module_FOUND Development.Embed_FOUND) + unset(Python2_${item}) +endforeach() + +set(Python2_ARTIFACTS_PREFIX "_TEST") +find_package(Python2 REQUIRED COMPONENTS Interpreter Development) +if (NOT Python2_TEST_FOUND OR NOT Python2_FOUND) + message (FATAL_ERROR "Failed to find Python 2 (TEST prefix)") +endif() +if (NOT Python2_TEST_Development_FOUND OR NOT Python2_Development_FOUND) + message (FATAL_ERROR "Failed to find Python 2 'Development' component (TEST prefix)") +endif() +if (NOT Python2_TEST_Development.Module_FOUND OR NOT Python2_Development.Module_FOUND) + message (FATAL_ERROR "Failed to find Python 2 'Development.Module' component (TEST prefix)") +endif() +if (NOT Python2_TEST_Development.Embed_FOUND OR NOT Python2_Development.Embed_FOUND) + message (FATAL_ERROR "Failed to find Python 2 'Development.Embed' component (TEST prefix)") +endif() + +if(NOT TARGET Python2_TEST::Interpreter) + message(SEND_ERROR "Python2_TEST::Interpreter not found") +endif() + +if(NOT TARGET Python2_TEST::Python) + message(SEND_ERROR "Python2_TEST::Python not found") +endif() +if(NOT TARGET Python2_TEST::Module) + message(SEND_ERROR "Python2_TEST::Module not found") +endif() + +Python2_TEST_add_library (TEST_spam2 MODULE ../TEST_spam.c) +target_compile_definitions (TEST_spam2 PRIVATE PYTHON2) + +add_test (NAME python2_TEST_spam2 + COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$" + "${Python2_INTERPRETER}" -c "import TEST_spam2; TEST_spam2.system(\"cd\")") diff --git a/Tests/FindPython/Python3/CMakeLists.txt b/Tests/FindPython/Python3/CMakeLists.txt index 28f68e16ba..bac6ed5c3d 100644 --- a/Tests/FindPython/Python3/CMakeLists.txt +++ b/Tests/FindPython/Python3/CMakeLists.txt @@ -102,3 +102,44 @@ add_test(NAME python3_find_invalid_abi -DPython3_FIND_STRATEGY=${Python3_FIND_STRATEGY} "-DPython3_FIND_ABI=${Python3_INVALID_ABI}" -P "${CMAKE_CURRENT_LIST_DIR}/../FindPythonScript.cmake") + + +# +# New search with user's prefix +# +foreach(item IN ITEMS FOUND Development_FOUND Development.Module_FOUND Development.Embed_FOUND) + unset(Python3_${item}) +endforeach() + +set(Python3_ARTIFACTS_PREFIX "_TEST") +find_package(Python3 REQUIRED COMPONENTS Interpreter Development) +if (NOT Python3_TEST_FOUND OR NOT Python3_FOUND) + message (FATAL_ERROR "Failed to find Python 3 (TEST prefix)") +endif() +if (NOT Python3_TEST_Development_FOUND OR NOT Python3_Development_FOUND) + message (FATAL_ERROR "Failed to find Python 3 'Development' component (TEST prefix)") +endif() +if (NOT Python3_TEST_Development.Module_FOUND OR NOT Python3_Development.Module_FOUND) + message (FATAL_ERROR "Failed to find Python 3 'Development.Module' component (TEST prefix)") +endif() +if (NOT Python3_TEST_Development.Embed_FOUND OR NOT Python3_Development.Embed_FOUND) + message (FATAL_ERROR "Failed to find Python 3 'Development.Embed' component (TEST prefix)") +endif() + +if(NOT TARGET Python3_TEST::Interpreter) + message(SEND_ERROR "Python3_TEST::Interpreter not found") +endif() + +if(NOT TARGET Python3_TEST::Python) + message(SEND_ERROR "Python3_TEST::Python not found") +endif() +if(NOT TARGET Python3_TEST::Module) + message(SEND_ERROR "Python3_TEST::Module not found") +endif() + +Python3_TEST_add_library (TEST_spam3 MODULE ../TEST_spam.c) +target_compile_definitions (TEST_spam3 PRIVATE PYTHON3) + +add_test (NAME python3_TEST_spam3 + COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$" + "${Python3_TEST_INTERPRETER}" -c "import TEST_spam3; TEST_spam3.system(\"cd\")") diff --git a/Tests/FindPython/TEST_spam.c b/Tests/FindPython/TEST_spam.c new file mode 100644 index 0000000000..a53bf830b1 --- /dev/null +++ b/Tests/FindPython/TEST_spam.c @@ -0,0 +1,41 @@ +#define Py_LIMITED_API 3 +#include + +static PyObject* spam_system(PyObject* self, PyObject* args) +{ + const char* command; + int sts; + + if (!PyArg_ParseTuple(args, "s", &command)) + return NULL; + sts = system(command); + /* return PyLong_FromLong(sts); */ + return Py_BuildValue("i", sts); +} + +static PyMethodDef SpamMethods[] = { + { "system", spam_system, METH_VARARGS, "Execute a shell command." }, + { NULL, NULL, 0, NULL } /* Sentinel */ +}; + +#if defined(PYTHON2) +PyMODINIT_FUNC initTEST_spam2(void) +{ + (void)Py_InitModule("TEST_spam2", SpamMethods); +} +#endif + +#if defined(PYTHON3) +static struct PyModuleDef spammodule = { + PyModuleDef_HEAD_INIT, "TEST_spam3", /* name of module */ + NULL, /* module documentation, may be NULL */ + -1, /* size of per-interpreter state of the module, + or -1 if the module keeps state in global variables. */ + SpamMethods +}; + +PyMODINIT_FUNC PyInit_TEST_spam3(void) +{ + return PyModule_Create(&spammodule); +} +#endif