From dd4fb6624130460dc5ab767b1bc0f22d4d4ad412 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Thu, 3 Oct 2024 16:54:51 -0600 Subject: [PATCH] SQUASH AGAINST: Change to find_package(Python3), set Python3_EXECUTABLE to PYTHON_EXECUTABLE (#610) NOTE: This passes the unit tests for tribits_find_python_interp() but not all of the TriBITS tests, yet. These changes need to be propagated across the rest of TriBITS. --- test/core/CMakeLists.txt | 2 +- .../core/TestingFunctionMacro_UnitTests.cmake | 92 +++++++++++++++---- .../TribitsFindPythonInterp.cmake | 35 ++++++- tribits/doc/guides/TribitsGuidesBody.rst | 28 +++--- 4 files changed, 120 insertions(+), 37 deletions(-) diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt index 6460753c8..1b68b8dfd 100644 --- a/test/core/CMakeLists.txt +++ b/test/core/CMakeLists.txt @@ -49,7 +49,7 @@ tribits_add_advanced_test( TestingFunctionMacro_UnitTests -D${PROJECT_NAME}_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} -P "${CMAKE_CURRENT_SOURCE_DIR}/TestingFunctionMacro_UnitTests.cmake" PASS_REGULAR_EXPRESSION_ALL - "Final UnitTests Result: num_run = 720" + "Final UnitTests Result: num_run = 724" "Final UnitTests Result: PASSED" ) diff --git a/test/core/TestingFunctionMacro_UnitTests.cmake b/test/core/TestingFunctionMacro_UnitTests.cmake index 8673ac350..0f0aad3ac 100644 --- a/test/core/TestingFunctionMacro_UnitTests.cmake +++ b/test/core/TestingFunctionMacro_UnitTests.cmake @@ -157,6 +157,8 @@ function(unittest_tribits_create_reverse_list) endfunction() +########################################################################################## + function(unittest_tribits_find_python_interp) message("\n***") @@ -166,55 +168,107 @@ function(unittest_tribits_find_python_interp) set(MESSAGE_WRAPPER_UNIT_TEST_MODE TRUE) set(TRIBITS_FIND_PYTHON_UNITTEST TRUE) + tribits_find_python_interp_uses_python_false() + tribits_find_python_interp_uses_python_empty() + tribits_find_python_interp_uses_python_true() + tribits_find_python_interp_requires_python_true() + tribits_find_python_interp_find_version_too_low() + tribits_find_python_interp_find_version_higher() + tribits_find_python_interp_python_executable_backward_compatible() + +endfunction() + + +function(tribits_find_python_interp_uses_python_false) message("tribits_find_python_interp(): ${PROJECT_NAME}_USES_PYTHON=FALSE") set(${PROJECT_NAME}_USES_PYTHON FALSE) global_set(MESSAGE_WRAPPER_INPUT) tribits_find_python_interp() unittest_compare_const(MESSAGE_WRAPPER_INPUT "-- ;NOTE: Skipping check for Python because; ${PROJECT_NAME}_USES_PYTHON='FALSE'") - unittest_compare_const(FIND_PythonInterp_ARGS + unittest_compare_const(FIND_Python3_ARGS "") +endfunction() - message("tribits_find_python_interp(): ${PROJECT_NAME}_USES_PYTHON=") - global_set(MESSAGE_WRAPPER_INPUT) - set(${PROJECT_NAME}_USES_PYTHON) - set(PYTHON_EXECUTABLE_UNITTEST_VAL /path/to/python2.4) + +function(tribits_find_python_interp_uses_python_empty) + message("tribits_find_python_interp(): ${PROJECT_NAME}_USES_PYTHON=''") + global_set(MESSAGE_WRAPPER_INPUT "") + set(${PROJECT_NAME}_USES_PYTHON "") + set(Python3_EXECUTABLE_UNITTEST_VAL /path/to/python3.8) tribits_find_python_interp() unittest_compare_const(MESSAGE_WRAPPER_INPUT - "-- ;Python3_EXECUTABLE='/path/to/python2.4'") + "-- ;Python3_EXECUTABLE='/path/to/python3.8'") +endfunction() + +function(tribits_find_python_interp_uses_python_true) message("tribits_find_python_interp(): ${PROJECT_NAME}_USES_PYTHON=TRUE") global_set(MESSAGE_WRAPPER_INPUT) set(${PROJECT_NAME}_USES_PYTHON TRUE) - global_set(PYTHON_EXECUTABLE_UNITTEST_VAL /path/to/python2.4) + global_set(Python3_EXECUTABLE_UNITTEST_VAL /path/to/python3.8) tribits_find_python_interp() unittest_compare_const(MESSAGE_WRAPPER_INPUT - "-- ;Python3_EXECUTABLE='/path/to/python2.4'") - unittest_compare_const(FIND_PythonInterp_ARGS - "PythonInterp") + "-- ;Python3_EXECUTABLE='/path/to/python3.8'") + unittest_compare_const(FIND_Python3_ARGS + "Python3;3.8") +endfunction() + +function(tribits_find_python_interp_requires_python_true) message("tribits_find_python_interp(): ${PROJECT_NAME}_REQUIRES_PYTHON=TRUE") global_set(MESSAGE_WRAPPER_INPUT) set(${PROJECT_NAME}_USES_PYTHON FALSE) set(${PROJECT_NAME}_REQUIRES_PYTHON TRUE) - set(PYTHON_EXECUTABLE_UNITTEST_VAL /path/to/python2.4) + set(Python3_EXECUTABLE_UNITTEST_VAL /path/to/python3.8) tribits_find_python_interp() unittest_compare_const(MESSAGE_WRAPPER_INPUT - "-- ;Python3_EXECUTABLE='/path/to/python2.4'") - unittest_compare_const(FIND_PythonInterp_ARGS - "PythonInterp;REQUIRED") + "-- ;Python3_EXECUTABLE='/path/to/python3.8'") + unittest_compare_const(FIND_Python3_ARGS + "Python3;3.8;REQUIRED") +endfunction() + - message("tribits_find_python_interp(): PythonInterp_FIND_VERSION=2.3") +function(tribits_find_python_interp_find_version_too_low) + message("tribits_find_python_interp(): ${PROJECT_NAME}_Python3_FIND_VERSION=3.7 (too low)") global_set(MESSAGE_WRAPPER_INPUT) - set(PythonInterp_FIND_VERSION 2.3) - set(PYTHON_EXECUTABLE_UNITTEST_VAL /dummy) + set(${PROJECT_NAME}_Python3_FIND_VERSION 3.7) + set(Python3_EXECUTABLE_UNITTEST_VAL /dummy) tribits_find_python_interp() unittest_compare_const(MESSAGE_WRAPPER_INPUT - "FATAL_ERROR;Error,; PythonInterp_FIND_VERSION=2.3 < 2.6; is not allowed!;-- ;Python3_EXECUTABLE='/dummy'") + "FATAL_ERROR;Error,; ${PROJECT_NAME}_Python3_FIND_VERSION=3.7 < 3.8; is not allowed!;-- ;Python3_EXECUTABLE='/dummy'") +endfunction() + + +function(tribits_find_python_interp_find_version_higher) + message("tribits_find_python_interp(): ${PROJECT_NAME}_Python3_FIND_VERSION=3.11") + global_set(MESSAGE_WRAPPER_INPUT) + set(${PROJECT_NAME}_REQUIRES_PYTHON TRUE) + set(${PROJECT_NAME}_Python3_FIND_VERSION 3.11) + set(Python3_EXECUTABLE_UNITTEST_VAL /path/to/python3.11) + tribits_find_python_interp() + unittest_compare_const(MESSAGE_WRAPPER_INPUT + "-- ;Python3_EXECUTABLE='/path/to/python3.11'") + unittest_compare_const(FIND_Python3_ARGS + "Python3;3.11;REQUIRED") +endfunction() + +function(tribits_find_python_interp_python_executable_backward_compatible) + message("tribits_find_python_interp(): PYTHON_EXECUTABLE backward compatibility") + global_set(MESSAGE_WRAPPER_INPUT) + set(PYTHON_EXECUTABLE /path/to/python3.10.2) + tribits_find_python_interp() + unittest_compare_const(MESSAGE_WRAPPER_INPUT + "DEPRECATION;Python3_EXECUTABLE being set by default to PYTHON_EXECUTABLE = '/path/to/python3.10.2' is deprecated!;\n\nNOTE: To Make these warnings go away, set -D; TRIBITS_HANDLE_TRIBITS_DEPRECATED_CODE=IGNORE (see the build reference guide).;-- ;Python3_EXECUTABLE='/path/to/python3.10.2'") + unittest_compare_const(FIND_Python3_ARGS + "Python3;3.8") endfunction() +########################################################################################## + + function(unittest_tribits_standardize_abs_paths) message("\n***") @@ -4844,4 +4898,4 @@ message("*** Determine final result of all unit tests") message("***\n") # Pass in the number of expected tests that must pass! -unittest_final_result(720) +unittest_final_result(724) diff --git a/tribits/core/package_arch/TribitsFindPythonInterp.cmake b/tribits/core/package_arch/TribitsFindPythonInterp.cmake index 430488163..50c78ea8a 100644 --- a/tribits/core/package_arch/TribitsFindPythonInterp.cmake +++ b/tribits/core/package_arch/TribitsFindPythonInterp.cmake @@ -7,26 +7,55 @@ # ***************************************************************************** # @HEADER + # Find Python executable which is needed for dependency file building macro(tribits_find_python) + # Get minimum version of Python to find + set(${PROJECT_NAME}_Python3_FIND_VERSION_MIN "3.8") + if ("${${PROJECT_NAME}_Python3_FIND_VERSION_DEFAULT}" STREQUAL "") + set(${PROJECT_NAME}_Python3_FIND_VERSION_DEFAULT + "${${PROJECT_NAME}_Python3_FIND_VERSION_MIN}") + endif() + advanced_set(${PROJECT_NAME}_Python3_FIND_VERSION + ${${PROJECT_NAME}_Python3_FIND_VERSION_DEFAULT} + CACHE STRING + "Default version of Python to find (must be ${${PROJECT_NAME}_Python3_FIND_VERSION_DEFAULT} or greater") + if (${PROJECT_NAME}_Python3_FIND_VERSION VERSION_LESS + "${${PROJECT_NAME}_Python3_FIND_VERSION_MIN}" + ) + message_wrapper(FATAL_ERROR "Error," + " ${PROJECT_NAME}_Python3_FIND_VERSION=${${PROJECT_NAME}_Python3_FIND_VERSION} < ${${PROJECT_NAME}_Python3_FIND_VERSION_MIN}" + " is not allowed!" ) + endif() + # Provide backward compatibility for user setting PYTHON_EXECUTABLE if ((NOT "${PYTHON_EXECUTABLE}" STREQUAL "") AND ("${Python3_EXECUTABLE}" STREQUAL "")) tribits_deprecated("Python3_EXECUTABLE being set by default to PYTHON_EXECUTABLE = '${PYTHON_EXECUTABLE}' is deprecated!") set(Python3_EXECUTABLE "${PYTHON_EXECUTABLE}" CACHE FILEPATH "Set by default to PYTHON_EXECUTABLE!") endif() + # Find Python if (${PROJECT_NAME}_REQUIRES_PYTHON) set(Python3_REQUIRED_ARG "REQUIRED") else() set(Python3_REQUIRED_ARG "") endif() - if (TRIBITS_FIND_PYTHON_UNITTEST) - set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE_UNITTEST_VAL}) + set(FIND_Python3_ARGS + Python3 ${${PROJECT_NAME}_Python3_FIND_VERSION} ${Python3_REQUIRED_ARG}) + if(NOT "${Python3_EXECUTABLE}" STREQUAL "") + # Already set, don't need to call anything! + elseif (TRIBITS_FIND_PYTHON_UNITTEST) + set(Python3_EXECUTABLE ${Python3_EXECUTABLE_UNITTEST_VAL}) else() - find_package(Python3 ${Python3_REQUIRED_ARG}) + find_package(${FIND_Python3_ARGS}) endif() endmacro() +# Select the minimum version of Python + + + + # TriBITS Wrapper for finding Python (or not) for a TriBITS project. macro(tribits_find_python_interp) if (${PROJECT_NAME}_REQUIRES_PYTHON) diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index 6991626c1..963755c88 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -7003,17 +7003,16 @@ Python Support TriBITS Core does not require anything other than raw CMake. However, Python Utils, TriBITS CI Support, and other extended TriBITS components require -Python. These extra TriBITS tools only require Python 2.7+ (and 3.x). By -default, when a TriBITS project starts to configure using CMake, it will try -to find Python 2.7+ on the system (see `Full Processing of TriBITS Project -Files`_). If Python is found, it will set the global cache variable -``Python3_EXECUTABLE``. If it is not found, then it will print a warning and -``Python3_EXECUTABLE`` will be empty. With this default behavior, if Python is -found, then the TriBITS project can use it. Otherwise, it can do without it. +Python. These extra TriBITS tools only require Python 3.8+. By default, when +a TriBITS project starts to configure using CMake, it will try to find Python +3.8+ on the system (see `Full Processing of TriBITS Project Files`_). If +Python is found, it will set the global cache variable ``Python3_EXECUTABLE``. +If it is not found, then it will print a warning and ``Python3_EXECUTABLE`` +will be empty. With this default behavior, if Python is found, then the +TriBITS project can use it. Otherwise, it can do without it. While the default behavior for finding Python described above is useful for -many TriBITS project (such as Trilinos), some TriBITS projects need different -behavior such as: +many TriBITS projects, some TriBITS projects need different behavior such as: 1. The TriBITS project may not ever use Python so there is no need to look for it at all. In this case, the TriBITS project would set @@ -7023,11 +7022,12 @@ behavior such as: can't be found. In this case, the TriBITS project would set `${PROJECT_NAME}_REQUIRES_PYTHON`_ to ``TRUE``. -3. Some TriBITS projects may require a version of Python more recent than 2.7. - In this case, the TriBITS project would set `PythonInterp_FIND_VERSION`_ to - some value higher than ``2.7``. For example, may newer systems have only - Python 3.5.2 or higher versions installed by default and projects developed - on such a system typically requires this version or higher. +3. Some TriBITS projects may require a version of Python more recent than 3.8. + In this case, the TriBITS project would set + `${PROJECT_NAME}_Python3_FIND_VERSION`_ to some value higher than ``3.8``. + For example, may newer systems have higher versions of Python installed by + default, and projects developed on such a system typically require this + version or higher. Project-Specific Build Reference