From 91e227939c8959285bf8f4c312bd634c9e8f8266 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Fri, 31 Jul 2026 16:41:01 +0200 Subject: [PATCH] FindPython: Add Python_SOSABI_PLATFORM variable This variable gives the SABI module extension which include the platform triplet. Fixes: #27997 --- .../dev/FindPython-SOSABI_PLATFORM.rst | 7 +++ Modules/FindPython.cmake | 17 ++++++- Modules/FindPython/Support.cmake | 48 ++++++++++++++----- Modules/FindPython3.cmake | 17 ++++++- .../FindPython/Python3SABIModule.cmake | 15 ++++++ 5 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 Help/release/dev/FindPython-SOSABI_PLATFORM.rst diff --git a/Help/release/dev/FindPython-SOSABI_PLATFORM.rst b/Help/release/dev/FindPython-SOSABI_PLATFORM.rst new file mode 100644 index 0000000000..71efcd1b92 --- /dev/null +++ b/Help/release/dev/FindPython-SOSABI_PLATFORM.rst @@ -0,0 +1,7 @@ +FindPython-SOSABI_PLATFORM +-------------------------- + +* The :module:`FindPython3` and :module:`FindPython` modules gained, + respectively, the variable ``Python3_SOSABI_PLATFORM`` and + ``Python_SOSABI_PLATFORM`` which gives, on some platforms, for the Stable + Application Binary Interface, the extension including the platform triplet. diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 381147d30e..3734ed9cd4 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -213,7 +213,7 @@ This module defines the following variables Information computed from ``sysconfig.get_config_var('EXT_SUFFIX')`` or ``sysconfig.get_config_var('SOABI')`` or - ``python3-config --extension-suffix``. + ``python-config --extension-suffix``. ``Python_SOSABI`` .. versionadded:: 3.26 @@ -225,6 +225,16 @@ This module defines the following variables or ``abi3t`` except for ``Windows``, ``MSYS`` and ``CYGWIN`` for which this is an empty string. +``Python_SOSABI_PLATFORM`` + .. versionadded:: 4.5 + + Extension suffix, with the platform triplet, for modules using the Stable + Application Binary Interface. This information is only available on some + platforms. This is an empty string for the other platforms. + + Information computed from ``importlib.machinery.EXTENSION_SUFFIXES`` if the + COMPONENT ``Interpreter`` was specified. Otherwise, this is an empty string. + ``Python_Compiler_FOUND`` Boolean indicating whether system has the Python compiler. ``Python_COMPILER`` @@ -682,6 +692,11 @@ If the library type is not specified, ``MODULE`` is assumed. When option ``WITH_SOABI`` is also specified, the module suffix will include the ``Python_SOSABI`` value, if any. +.. versionadded:: 4.5 + If the sub-option ``PLATFORM`` of ``WITH_SOABI`` option is specified, the + module suffix will include preferably the ``Python_SOSABI_PLATFORM`` value, + if any or, as fallback, the ``Python_SOSABI`` value. + .. versionadded:: 3.30 For ``MODULE`` type, the :prop_tgt:`DEBUG_POSTFIX` target property is initialized with the value of ``Python_DEBUG_POSTFIX`` variable if defined. diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index f5f7576b68..968bb6cf40 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -14,6 +14,8 @@ cmake_policy(PUSH) cmake_policy (SET CMP0124 NEW) # registry view behavior cmake_policy (SET CMP0134 NEW) +# return(PROPAGATE) +cmake_policy(SET CMP0140 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_ cmake_policy(SET CMP0159 NEW) @@ -768,7 +770,7 @@ except Exception: import sys import re import importlib.machinery -sys.stdout.write(next(filter(lambda x: re.search('^\\.abi', x), importlib.machinery.EXTENSION_SUFFIXES))) +sys.stdout.write(';'.join(filter(lambda x: re.search('^\\.abi', x), importlib.machinery.EXTENSION_SUFFIXES))) ]==] RESULT_VARIABLE _result OUTPUT_VARIABLE _values @@ -777,7 +779,7 @@ sys.stdout.write(next(filter(lambda x: re.search('^\\.abi', x), importlib.machin if (_result) unset (_values) else() - string (REGEX REPLACE "^\\.(.+)\\.[^.]+$" "\\1" _values "${_values}") + list (TRANSFORM _values REPLACE "^\\.(.+)\\.[^.]+$" "\\1") endif() elseif (NAME STREQUAL "ABIFLAGS" AND WIN32) # config var ABIFLAGS does not exist for version < 3.14, check GIL specific variable @@ -851,6 +853,18 @@ except Exception: set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE) endfunction() +function (_PYTHON_GET_SOSABI) + _python_get_config_var (sosabi SOSABI) + if (sosabi MATCHES "(^|.+;)(abi${${_PYTHON_PREFIX}_VERSION_MAJOR}t?)(;.+|$)") + set (${_PYTHON_PREFIX}_SOSABI "${CMAKE_MATCH_2}") + endif() + if (sosabi MATCHES "(^|.+;)(abi${${_PYTHON_PREFIX}_VERSION_MAJOR}t?-[^;]+)(;.+|$)") + set (${_PYTHON_PREFIX}_SOSABI_PLATFORM "${CMAKE_MATCH_2}") + endif() + + return (PROPAGATE ${_PYTHON_PREFIX}_SOSABI ${_PYTHON_PREFIX}_SOSABI_PLATFORM) +endfunction() + function (_PYTHON_GET_VERSION) cmake_parse_arguments (PARSE_ARGV 0 _PGV "LIBRARY;SABI_LIBRARY;INCLUDE" "PREFIX" "") @@ -1728,6 +1742,7 @@ else() endif() unset (${_PYTHON_PREFIX}_SOABI) unset (${_PYTHON_PREFIX}_SOSABI) +unset (${_PYTHON_PREFIX}_SOSABI_PLATFORM) unset (${_PYTHON_PREFIX}_FREE_THREADED) # Windows CPython implementation may be requiring a postfix in debug mode @@ -2456,11 +2471,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 5 _${_PYTHON_PREFIX}_ABIFLAGS) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 6 ${_PYTHON_PREFIX}_SOABI) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 7 ${_PYTHON_PREFIX}_SOSABI) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 8 ${_PYTHON_PREFIX}_SOSABI_PLATFORM) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 8 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 9 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 10 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 11 ${_PYTHON_PREFIX}_SITEARCH) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 9 ${_PYTHON_PREFIX}_STDLIB) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 10 ${_PYTHON_PREFIX}_STDARCH) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 11 ${_PYTHON_PREFIX}_SITELIB) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 12 ${_PYTHON_PREFIX}_SITEARCH) else() string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) @@ -2595,11 +2611,11 @@ else: endif() _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) - _python_get_config_var (${_PYTHON_PREFIX}_SOSABI SOSABI) + _python_get_sosabi () # store properties in the cache to speed-up future searches set (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES - "${${_PYTHON_PREFIX}_INTERPRETER_ID};${${_PYTHON_PREFIX}_VERSION_MAJOR};${${_PYTHON_PREFIX}_VERSION_MINOR};${${_PYTHON_PREFIX}_VERSION_PATCH};${_${_PYTHON_PREFIX}_ARCH};${_${_PYTHON_PREFIX}_ABIFLAGS};${${_PYTHON_PREFIX}_SOABI};${${_PYTHON_PREFIX}_SOSABI};${${_PYTHON_PREFIX}_STDLIB};${${_PYTHON_PREFIX}_STDARCH};${${_PYTHON_PREFIX}_SITELIB};${${_PYTHON_PREFIX}_SITEARCH}" CACHE INTERNAL "${_PYTHON_PREFIX} Properties") + "${${_PYTHON_PREFIX}_INTERPRETER_ID};${${_PYTHON_PREFIX}_VERSION_MAJOR};${${_PYTHON_PREFIX}_VERSION_MINOR};${${_PYTHON_PREFIX}_VERSION_PATCH};${_${_PYTHON_PREFIX}_ARCH};${_${_PYTHON_PREFIX}_ABIFLAGS};${${_PYTHON_PREFIX}_SOABI};${${_PYTHON_PREFIX}_SOSABI};${${_PYTHON_PREFIX}_SOSABI_PLATFORM};${${_PYTHON_PREFIX}_STDLIB};${${_PYTHON_PREFIX}_STDARCH};${${_PYTHON_PREFIX}_SITELIB};${${_PYTHON_PREFIX}_SITEARCH}" CACHE INTERNAL "${_PYTHON_PREFIX} Properties") else() unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE) unset (${_PYTHON_PREFIX}_INTERPRETER_ID) @@ -4226,7 +4242,7 @@ if (("Development.Module" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS endif() if (NOT DEFINED ${_PYTHON_PREFIX}_SOSABI) - _python_get_config_var (${_PYTHON_PREFIX}_SOSABI SOSABI) + _python_get_sosabi() endif() if (WIN32 AND NOT DEFINED ${_PYTHON_PREFIX}_DEBUG_POSTFIX) @@ -4604,7 +4620,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") # It is used to build modules for python. # function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE;WITH_SOABI" "USE_SABI" "") + cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE;WITH_SOABI;PLATFORM" "USE_SABI" "") if (PYTHON_ADD_LIBRARY_STATIC) set (type STATIC) @@ -4670,6 +4686,12 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") get_property (type TARGET ${name} PROPERTY TYPE) if (type STREQUAL "MODULE_LIBRARY") + if ((NOT PYTHON_ADD_LIBRARY_USE_SABI OR NOT PYTHON_ADD_LIBRARY_WITH_SOABI) + AND PYTHON_ADD_LIBRARY_PLATFORM) + message (AUTHOR_WARNING "Find${prefix}: Option 'PLATFORM' is only valid with options 'USE_SABI' and 'WITH_SOABI'.") + unset(PYTHON_ADD_LIBRARY_PLATFORM) + endif() + if (PYTHON_ADD_LIBRARY_USE_SABI) if (${prefix}_FREE_THREADED AND "${major_version}.${minor_version}" VERSION_GREATER_EQUAL "3.15") @@ -4703,7 +4725,11 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") if (NOT suffix) set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}") endif() - set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOSABI}${suffix}") + if (PYTHON_ADD_LIBRARY_PLATFORM AND ${prefix}_SOSABI_PLATFORM) + set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOSABI_PLATFORM}${suffix}") + else() + set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOSABI}${suffix}") + endif() endif() endif() else() diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 657587ec00..c8c3ba8ceb 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -227,6 +227,16 @@ This module defines the following variables or ``abi3t`` except for ``Windows``, ``MSYS`` and ``CYGWIN`` for which this is an empty string. +``Python3_SOSABI_PLATFORM`` + .. versionadded:: 4.5 + + Extension suffix, with the platform triplet, for modules using the Stable + Application Binary Interface. This information is only available on some + platforms. This is an empty string for the other platforms. + + Information computed from ``importlib.machinery.EXTENSION_SUFFIXES`` if the + COMPONENT ``Interpreter`` was specified. Otherwise, this is an empty string. + ``Python3_Compiler_FOUND`` Boolean indicating whether system has the Python 3 compiler. ``Python3_COMPILER`` @@ -653,7 +663,7 @@ of Python module naming rules: .. code-block:: cmake - Python3_add_library ( [STATIC | SHARED | MODULE [USE_SABI ] [WITH_SOABI]] + Python3_add_library ( [STATIC | SHARED | MODULE [USE_SABI ] [WITH_SOABI [PLATFORM]]] [ ...]) If the library type is not specified, ``MODULE`` is assumed. @@ -681,6 +691,11 @@ If the library type is not specified, ``MODULE`` is assumed. When option ``WITH_SOABI`` is also specified, the module suffix will include the ``Python3_SOSABI`` value, if any. +.. versionadded:: 4.5 + If the sub-option ``PLATFORM`` of ``WITH_SOABI`` option is specified, the + module suffix will include preferably the ``Python3_SOSABI_PLATFORM`` value, + if any or, as fallback, the ``Python3_SOSABI`` value. + .. versionadded:: 3.30 For ``MODULE`` type, the :prop_tgt:`DEBUG_POSTFIX` target property is initialized with the value of ``Python3_DEBUG_POSTFIX`` variable if defined. diff --git a/Tests/RunCMake/FindPython/Python3SABIModule.cmake b/Tests/RunCMake/FindPython/Python3SABIModule.cmake index a8eed7e25b..222e7c5ab1 100644 --- a/Tests/RunCMake/FindPython/Python3SABIModule.cmake +++ b/Tests/RunCMake/FindPython/Python3SABIModule.cmake @@ -47,6 +47,21 @@ if (Python3_SOSABI) endif() endif() +Python3_add_library (spam3_2 MODULE USE_SABI 3 WITH_SOABI PLATFORM spam.c) +target_compile_definitions (spam3_2 PRIVATE PYTHON3) + +if (Python3_SOSABI_PLATFORM) + get_property (suffix TARGET spam3_2 PROPERTY SUFFIX) + if (NOT suffix MATCHES "^\\.${Python3_SOSABI_PLATFORM}") + message(FATAL_ERROR "Module suffix do not include Python3_SOSABI_PLATFORM") + endif() +elseif(Python3_SOSABI) + get_property (suffix TARGET spam3_2 PROPERTY SUFFIX) + if (NOT suffix MATCHES "^\\.${Python3_SOSABI}") + message(FATAL_ERROR "Module suffix do not include Python3_SOSABI") + endif() +endif() + add_test (NAME python3_spam3 COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$"