From 0a4a4d2053802bd760a367e4ef6f717e985755ed Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Sun, 17 Aug 2025 18:04:27 +0200 Subject: FindPython: NumPy target does not depend on Development.Module Fixes: #27123 --- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0201.rst | 36 ++++++++++++++++++++++ Help/release/dev/FindPython-NumPy-target.rst | 5 +++ Modules/FindPython.cmake | 15 +++++++-- Modules/FindPython/Support.cmake | 35 ++++++++++++++++----- Modules/FindPython2.cmake | 15 +++++++-- Modules/FindPython3.cmake | 15 +++++++-- Source/cmPolicies.h | 4 +++ Tests/RunCMake/FindPython/NumPy-CMP0201-NEW.cmake | 3 ++ Tests/RunCMake/FindPython/NumPy-CMP0201-OLD.cmake | 3 ++ .../FindPython/NumPyOnly-CMP0201-NEW.cmake | 3 ++ .../FindPython/NumPyOnly-CMP0201-OLD.cmake | 3 ++ Tests/RunCMake/FindPython/NumPyOnly.cmake | 10 ++++-- Tests/RunCMake/FindPython/NumPySABIModule.cmake | 15 +++++++++ Tests/RunCMake/FindPython/RunCMakeTest.cmake | 25 ++++++++++----- 15 files changed, 162 insertions(+), 26 deletions(-) create mode 100644 Help/policy/CMP0201.rst create mode 100644 Help/release/dev/FindPython-NumPy-target.rst create mode 100644 Tests/RunCMake/FindPython/NumPy-CMP0201-NEW.cmake create mode 100644 Tests/RunCMake/FindPython/NumPy-CMP0201-OLD.cmake create mode 100644 Tests/RunCMake/FindPython/NumPyOnly-CMP0201-NEW.cmake create mode 100644 Tests/RunCMake/FindPython/NumPyOnly-CMP0201-OLD.cmake create mode 100644 Tests/RunCMake/FindPython/NumPySABIModule.cmake diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 5b0d129..7f69785 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -98,6 +98,7 @@ Policies Introduced by CMake 4.2 .. toctree:: :maxdepth: 1 + CMP0201: The Python::NumPy target does not depend on the Python::Module target. CMP0200: Location and configuration selection for imported targets is more consistent. CMP0199: $ only matches the configuration of the consumed target. CMP0198: CMAKE_PARENT_LIST_FILE is not defined in CMakeLists.txt. diff --git a/Help/policy/CMP0201.rst b/Help/policy/CMP0201.rst new file mode 100644 index 0000000..f098cde --- /dev/null +++ b/Help/policy/CMP0201.rst @@ -0,0 +1,36 @@ +CMP0201 +------- + +.. versionadded:: 4.2 + +The modules :module:`FindPython3`, :module:`FindPython2` and +:module:`FindPython` change the handling of the ``NumPy`` +component and, respectively, the definition of the ``Python3::NumPy``, +``Python2::NumPy`` and ``Python::NumPy`` targets. + +For CMake 4.2 and above, the specification of the ``NumPy`` component does not +imply anymore the component ``Development.Module`` and the ``Python3::NumPy``, +``Python2::NumPy`` and ``Python::NumPy`` targets provided, respectively, by the +modules :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython` +do not depend on the ``Python3::Development.Module``, +``Python2::Development.Module`` and ``Python::Development.Module`` targets. +For CMake 4.1 and below, the specification of the ``NumPy`` component imply the +component ``Development.Module`` and the ``Python3::NumPy``, ``Python2::NumPy`` +and ``Python::NumPy`` targets provided, respectively, by the modules +:module:`FindPython3`, :module:`FindPython2` and :module:`FindPython` depend on +the ``Python3::Development.Module``, ``Python2::Development.Module`` and +``Python::Development.Module`` targets. + +The ``OLD`` behavior for this policy creates a dependency of the ``NumPy`` +target over the ``Development.Module`` target. The ``NEW`` behavior does not +create a dependency of the ``NumPy`` target over the ``Development.Module`` +target. + +This policy provides compatibility with projects that expect the legacy +behavior. + +.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2 +.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn +.. include:: include/STANDARD_ADVICE.rst + +.. include:: include/DEPRECATED.rst diff --git a/Help/release/dev/FindPython-NumPy-target.rst b/Help/release/dev/FindPython-NumPy-target.rst new file mode 100644 index 0000000..046cf68 --- /dev/null +++ b/Help/release/dev/FindPython-NumPy-target.rst @@ -0,0 +1,5 @@ +FindPython-NumPy-target +----------------------- + +* The ``Python::NumPy`` target does not depend on + the ``Python::Development.Module`` target. See policy :policy:`CMP0201`. diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 48744f2..be15557 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -42,10 +42,14 @@ The following components are supported: `Stable Application Binary Interface `_. This component is available only for version ``3.2`` and upper. -* ``NumPy``: search for NumPy include directories. - .. versionadded:: 3.14 - Added the ``NumPy`` component. + + * ``NumPy``: search for NumPy include directories. Specifying this component + imply also the components ``Interpreter`` and ``Development.Module``. + + .. versionchanged:: 4.2 + The component ``Development.Module`` is no longer implied when the policy + :policy:`CMP0201` is set to ``NEW``. If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed. @@ -138,6 +142,11 @@ This module provides the following :ref:`Imported Targets`: .. versionadded:: 3.14 NumPy Python library. Target defined if component ``NumPy`` is found. + Moreover, this target has the ``Python::Module`` target as dependency. + + .. versionchanged:: 4.2 + This target does not have anymore the ``Python::Module`` target as + dependency when the policy :policy:`CMP0201` is set to ``NEW``. Result Variables ^^^^^^^^^^^^^^^^ diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index a944164..df9d24d 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -1475,12 +1475,16 @@ endif() # handle components +cmake_policy (GET CMP0201 _${_PYTHON_PREFIX}_NUMPY_POLICY) 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_BASE}_FIND_COMPONENTS) - list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Interpreter" "Development.Module") + list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Interpreter") + if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW") + list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Development.Module") + endif() endif() if ("Development" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS) list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Development.Module" "Development.Embed") @@ -4050,7 +4054,12 @@ if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interp set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "") elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) # compute numpy signature. Depends on interpreter and development signatures - string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + set(__${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}") + if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW") + string(APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}") + endif() + string(APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}") if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE) @@ -4101,8 +4110,12 @@ if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interp unset (${_PYTHON_PREFIX}_NumPy_VERSION) endif() - # final step: set NumPy founded only if Development.Module component is founded as well - set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND}) + if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW") + # final step: set NumPy founded only if Development.Module component is founded as well + set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND}) + else() + set (${_PYTHON_PREFIX}_NumPy_FOUND TRUE) + endif() else() set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE) endif() @@ -4117,7 +4130,12 @@ if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interp unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE) # compute and save numpy signature - string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}") + set (__${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}") + if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW") + string (APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}") + endif() + string (APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}") + string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}") set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "") else() unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE) @@ -4454,11 +4472,14 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") endif() if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_NumPy_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND TARGET ${_PYTHON_PREFIX}::Module) + AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND + (_${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW" OR TARGET ${_PYTHON_PREFIX}::Module)) add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED) set_property (TARGET ${_PYTHON_PREFIX}::NumPy PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS}") - target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module) + if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW") + target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module) + endif() endif() endif() diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 9e86894..26d5794 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -35,10 +35,14 @@ The following components are supported: * ``Development.Embed``: search for artifacts for Python 2 embedding developments. -* ``NumPy``: search for NumPy include directories. - .. versionadded:: 3.14 - Added the ``NumPy`` component. + + * ``NumPy``: search for NumPy include directories. Specifying this component + imply also the components ``Interpreter`` and ``Development.Module``. + + .. versionchanged:: 4.2 + The component ``Development.Module`` is no longer implied when the policy + :policy:`CMP0201` is set to ``NEW``. If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed. @@ -125,6 +129,11 @@ This module provides the following :ref:`Imported Targets`: .. versionadded:: 3.14 NumPy library for Python 2. Target defined if component ``NumPy`` is found. + Moreover, this target has the ``Python2::Module`` target as dependency. + + .. versionchanged:: 4.2 + This target does not have anymore the ``Python2::Module`` target as + dependency when the policy :policy:`CMP0201` is set to ``NEW``. Result Variables ^^^^^^^^^^^^^^^^ diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 66c9d41..aaa6193 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -42,10 +42,14 @@ The following components are supported: `Stable Application Binary Interface `_. This component is available only for version ``3.2`` and upper. -* ``NumPy``: search for NumPy include directories. - .. versionadded:: 3.14 - Added the ``NumPy`` component. + + * ``NumPy``: search for NumPy include directories. Specifying this component + imply also the components ``Interpreter`` and ``Development.Module``. + + .. versionchanged:: 4.2 + The component ``Development.Module`` is no longer implied when the policy + :policy:`CMP0201` is set to ``NEW``. If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed. @@ -140,6 +144,11 @@ This module provides the following :ref:`Imported Targets`: .. versionadded:: 3.14 NumPy library for Python 3. Target defined if component ``NumPy`` is found. + Moreover, this target has the ``Python3::Module`` target as dependency. + + .. versionchanged:: 4.2 + This target does not have anymore the ``Python3::Module`` target as + dependency when the policy :policy:`CMP0201` is set to ``NEW``. Result Variables ^^^^^^^^^^^^^^^^ diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index e6ddb29..73fa7b3 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -600,6 +600,10 @@ class cmMakefile; SELECT(POLICY, CMP0200, \ "Location and configuration selection for imported targets is more " \ "consistent.", \ + 4, 2, 0, WARN) \ + SELECT(POLICY, CMP0201, \ + "The Python::NumPy target does not depend on the Python::Module " \ + "target.", \ 4, 2, 0, WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) diff --git a/Tests/RunCMake/FindPython/NumPy-CMP0201-NEW.cmake b/Tests/RunCMake/FindPython/NumPy-CMP0201-NEW.cmake new file mode 100644 index 0000000..c57ad17 --- /dev/null +++ b/Tests/RunCMake/FindPython/NumPy-CMP0201-NEW.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0201 NEW) + +include(NumPy.cmake) diff --git a/Tests/RunCMake/FindPython/NumPy-CMP0201-OLD.cmake b/Tests/RunCMake/FindPython/NumPy-CMP0201-OLD.cmake new file mode 100644 index 0000000..4bec78b --- /dev/null +++ b/Tests/RunCMake/FindPython/NumPy-CMP0201-OLD.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0201 OLD) + +include(NumPy.cmake) diff --git a/Tests/RunCMake/FindPython/NumPyOnly-CMP0201-NEW.cmake b/Tests/RunCMake/FindPython/NumPyOnly-CMP0201-NEW.cmake new file mode 100644 index 0000000..902292a --- /dev/null +++ b/Tests/RunCMake/FindPython/NumPyOnly-CMP0201-NEW.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0201 NEW) + +include(NumPyOnly.cmake) diff --git a/Tests/RunCMake/FindPython/NumPyOnly-CMP0201-OLD.cmake b/Tests/RunCMake/FindPython/NumPyOnly-CMP0201-OLD.cmake new file mode 100644 index 0000000..df53a1f --- /dev/null +++ b/Tests/RunCMake/FindPython/NumPyOnly-CMP0201-OLD.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0201 OLD) + +include(NumPyOnly.cmake) diff --git a/Tests/RunCMake/FindPython/NumPyOnly.cmake b/Tests/RunCMake/FindPython/NumPyOnly.cmake index 0f98da7..30e55e9 100644 --- a/Tests/RunCMake/FindPython/NumPyOnly.cmake +++ b/Tests/RunCMake/FindPython/NumPyOnly.cmake @@ -2,9 +2,15 @@ enable_language(C) include(CTest) +cmake_policy(GET CMP0201 numpy_policy) + +if(numpy_policy STREQUAL NEW) + set(components "Development.Module") +endif() + if(CMake_TEST_FindPython2_NumPy) - find_package (Python2 REQUIRED COMPONENTS NumPy) + find_package (Python2 REQUIRED COMPONENTS ${components} NumPy) Python2_add_library (arraytest2 MODULE arraytest.c) target_compile_definitions (arraytest2 PRIVATE PYTHON2) @@ -18,7 +24,7 @@ endif() if(CMake_TEST_FindPython3_NumPy) - find_package (Python3 REQUIRED COMPONENTS NumPy) + find_package (Python3 REQUIRED COMPONENTS ${components} NumPy) Python3_add_library (arraytest3 MODULE arraytest.c) target_compile_definitions (arraytest3 PRIVATE PYTHON3) diff --git a/Tests/RunCMake/FindPython/NumPySABIModule.cmake b/Tests/RunCMake/FindPython/NumPySABIModule.cmake new file mode 100644 index 0000000..d76a5c9 --- /dev/null +++ b/Tests/RunCMake/FindPython/NumPySABIModule.cmake @@ -0,0 +1,15 @@ +enable_language(C) + +include(CTest) + +cmake_policy(SET CMP0201 NEW) + +find_package (Python3 REQUIRED COMPONENTS Interpreter Development.SABIModule NumPy) + +Python3_add_library (arraytest3 MODULE USE_SABI 3.${Python3_VERSION_MINOR} WITH_SOABI arraytest.c) +target_compile_definitions (arraytest3 PRIVATE PYTHON3) +target_link_libraries (arraytest3 PRIVATE Python3::NumPy) + +add_test (NAME python3_arraytest + COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$" + "${Python3_INTERPRETER}" -c "import numpy; import arraytest3; arraytest3.vecsq(numpy.array([1, 2, 3]));") diff --git a/Tests/RunCMake/FindPython/RunCMakeTest.cmake b/Tests/RunCMake/FindPython/RunCMakeTest.cmake index f866015..b6eb192 100644 --- a/Tests/RunCMake/FindPython/RunCMakeTest.cmake +++ b/Tests/RunCMake/FindPython/RunCMakeTest.cmake @@ -350,14 +350,23 @@ if(CMake_TEST_FindPython_Various) endif() if(CMake_TEST_FindPython2_NumPy OR CMake_TEST_FindPython3_NumPy) - run_python(NumPy ACTION RUN - OPTIONS -DCMake_TEST_FindPython2_NumPy=${CMake_TEST_FindPython2_NumPy} - -DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}) - run_python(NumPyOnly ACTION RUN - OPTIONS -DCMake_TEST_FindPython2_NumPy=${CMake_TEST_FindPython2_NumPy} - -DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}) - if(CMake_TEST_FindPython3_NumPy) - custom_failure_message_check("NumPy" "Interpreter:Development:NumPy" -DPython3_NumPy_INCLUDE_DIR=/not/found/numpy/include) + run_python(NumPy-CMP0201-OLD ACTION RUN + OPTIONS -DCMake_TEST_FindPython2_NumPy=${CMake_TEST_FindPython2_NumPy} + -DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}) + run_python(NumPy-CMP0201-NEW ACTION RUN + OPTIONS -DCMake_TEST_FindPython2_NumPy=${CMake_TEST_FindPython2_NumPy} + -DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}) + run_python(NumPyOnly-CMP0201-OLD ACTION RUN + OPTIONS -DCMake_TEST_FindPython2_NumPy=${CMake_TEST_FindPython2_NumPy} + -DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}) + run_python(NumPyOnly-CMP0201-NEW ACTION RUN + OPTIONS -DCMake_TEST_FindPython2_NumPy=${CMake_TEST_FindPython2_NumPy} + -DCMake_TEST_FindPython3_NumPy=${CMake_TEST_FindPython3_NumPy}) + if(CMake_TEST_FindPython3_NumPy) + if(CMake_TEST_FindPython3_SABIModule) + run_python(NumPySABIModule ACTION RUN) + endif() + custom_failure_message_check("NumPy" "Interpreter:Development:NumPy" -DPython3_NumPy_INCLUDE_DIR=/not/found/numpy/include) endif() endif() -- cgit v0.12