Browse Source

Merge topic 'FindPython-NumPy-target'

0a4a4d2053 FindPython: NumPy target does not depend on Development.Module

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !11093
Brad King 1 month ago
parent
commit
f156d7fa1f

+ 1 - 0
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. </policy/CMP0201>
    CMP0200: Location and configuration selection for imported targets is more consistent. </policy/CMP0200>
    CMP0199: $<CONFIG> only matches the configuration of the consumed target. </policy/CMP0199>
    CMP0198: CMAKE_PARENT_LIST_FILE is not defined in CMakeLists.txt. </policy/CMP0198>

+ 36 - 0
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

+ 5 - 0
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`.

+ 12 - 3
Modules/FindPython.cmake

@@ -42,10 +42,14 @@ The following components are supported:
       `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_.
       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
 ^^^^^^^^^^^^^^^^

+ 28 - 7
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()
 

+ 12 - 3
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
 ^^^^^^^^^^^^^^^^

+ 12 - 3
Modules/FindPython3.cmake

@@ -42,10 +42,14 @@ The following components are supported:
       `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_.
       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
 ^^^^^^^^^^^^^^^^

+ 4 - 0
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)

+ 3 - 0
Tests/RunCMake/FindPython/NumPy-CMP0201-NEW.cmake

@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0201 NEW)
+
+include(NumPy.cmake)

+ 3 - 0
Tests/RunCMake/FindPython/NumPy-CMP0201-OLD.cmake

@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0201 OLD)
+
+include(NumPy.cmake)

+ 3 - 0
Tests/RunCMake/FindPython/NumPyOnly-CMP0201-NEW.cmake

@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0201 NEW)
+
+include(NumPyOnly.cmake)

+ 3 - 0
Tests/RunCMake/FindPython/NumPyOnly-CMP0201-OLD.cmake

@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0201 OLD)
+
+include(NumPyOnly.cmake)

+ 8 - 2
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)

+ 15 - 0
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=$<TARGET_FILE_DIR:arraytest3>"
+  "${Python3_INTERPRETER}" -c "import numpy; import arraytest3; arraytest3.vecsq(numpy.array([1, 2, 3]));")

+ 17 - 8
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()