From 776d27d4a4eb27f5618e682dafc1d44fba8598c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20M=C3=BCller?= Date: Fri, 20 Dec 2019 13:24:54 +0100 Subject: FindPython: Extend virtual environment handling by considering conda - Add functionality to recognize and use CONDA_PREFIX environment variable - Add tests for conda virtual environments - Fixes: #20111 --- Help/release/dev/FindPythonConda-module.rst | 5 +++ Modules/FindPython.cmake | 12 +++--- Modules/FindPython/Support.cmake | 14 +++---- Modules/FindPython2.cmake | 12 +++--- Modules/FindPython3.cmake | 12 +++--- Tests/CMakeLists.txt | 2 +- Tests/FindPython/CMakeLists.txt | 13 ++++++ Tests/FindPython/VirtualEnv/CMakeLists.txt | 4 ++ Tests/FindPython/VirtualEnvConda/CMakeLists.txt | 46 ++++++++++++++++++++++ .../VirtualEnvConda/VirtualEnvDefault.cmake | 6 +++ .../VirtualEnvConda/VirtualEnvOnly.cmake | 16 ++++++++ .../VirtualEnvConda/VirtualEnvStandard.cmake | 7 ++++ 12 files changed, 123 insertions(+), 26 deletions(-) create mode 100644 Help/release/dev/FindPythonConda-module.rst create mode 100644 Tests/FindPython/VirtualEnvConda/CMakeLists.txt create mode 100644 Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake create mode 100644 Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake create mode 100644 Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake diff --git a/Help/release/dev/FindPythonConda-module.rst b/Help/release/dev/FindPythonConda-module.rst new file mode 100644 index 0000000..d762fbf --- /dev/null +++ b/Help/release/dev/FindPythonConda-module.rst @@ -0,0 +1,5 @@ +FindPythonConda-module +---------------------- + +* The :module:`FindPython` module has learned to find Python components in active + virtual environments managed by ``conda``. diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 2bdfaf3..177ed58 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -220,12 +220,12 @@ Hints variable will be used, if any. ``Python_FIND_VIRTUALENV`` - This variable defines the handling of virtual environments. It is meaningfull - only when a virtual environment is active (i.e. the ``activate`` script has - been evaluated). In this case, it takes precedence over - ``Python_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` variables. - The ``Python_FIND_VIRTUALENV`` variable can be set to empty or one of the - following: + This variable defines the handling of virtual environments managed by + ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment + is active (i.e. the ``activate`` script has been evaluated). In this case, it + takes precedence over ``Python_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` + variables. The ``Python_FIND_VIRTUALENV`` variable can be set to empty or + one of the following: * ``FIRST``: The virtual environment is used before any other standard paths to look-up for the interpreter. This is the default. diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 0d6d2fc..b1dfa07 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -834,8 +834,8 @@ else() set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") endif() -# virtual environments handling -if (DEFINED ENV{VIRTUAL_ENV}) +# virtual environments recognition +if (DEFINED ENV{VIRTUAL_ENV} OR DEFINED ENV{CONDA_PREFIX}) if (DEFINED ${_PYTHON_PREFIX}_FIND_VIRTUALENV) if (NOT ${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$") message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_VIRTUALENV}: invalid value for '${_PYTHON_PREFIX}_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'STANDARD' expected. 'FIRST' will be used instead.") @@ -930,7 +930,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES ${_${_PYTHON_PREFIX}_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ENV VIRTUAL_ENV + PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX PATH_SUFFIXES bin Scripts NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH @@ -1050,7 +1050,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES ${_${_PYTHON_PREFIX}_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ENV VIRTUAL_ENV + PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX PATH_SUFFIXES bin Scripts NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH @@ -1555,7 +1555,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) + set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) endif() unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS) @@ -1786,7 +1786,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) + set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) endif() if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") @@ -2007,7 +2007,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) + set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) endif() unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 3cc7d56..9d4eda2 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -176,12 +176,12 @@ Hints variable will be used, if any. ``Python2_FIND_VIRTUALENV`` - This variable defines the handling of virtual environments. It is meaningfull - only when a virtual environment is active (i.e. the ``activate`` script has - been evaluated). In this case, it takes precedence over - ``Python2_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` variables. - The ``Python2_FIND_VIRTUALENV`` variable can be set to empty or one of the - following: + This variable defines the handling of virtual environments managed by + ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment + is active (i.e. the ``activate`` script has been evaluated). In this case, it + takes precedence over ``Python2_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` + variables. The ``Python2_FIND_VIRTUALENV`` variable can be set to empty or + one of the following: * ``FIRST``: The virtual environment is used before any other standard paths to look-up for the interpreter. This is the default. diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 066d0df..0a96fad 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -217,12 +217,12 @@ Hints variable will be used, if any. ``Python3_FIND_VIRTUALENV`` - This variable defines the handling of virtual environments. It is meaningfull - only when a virtual environment is active (i.e. the ``activate`` script has - been evaluated). In this case, it takes precedence over - ``Python3_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` variables. - The ``Python3_FIND_VIRTUALENV`` variable can be set to empty or one of the - following: + This variable defines the handling of virtual environments managed by + ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment + is active (i.e. the ``activate`` script has been evaluated). In this case, it + takes precedence over ``Python3_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` + variables. The ``Python3_FIND_VIRTUALENV`` variable can be set to empty or + one of the following: * ``FIRST``: The virtual environment is used before any other standard paths to look-up for the interpreter. This is the default. diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 59f5c73..90eed4f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1449,7 +1449,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH add_subdirectory(GoogleTest) endif() - if(CMake_TEST_FindPython OR CMake_TEST_FindPython_NumPy) + if(CMake_TEST_FindPython OR CMake_TEST_FindPython_NumPy OR CMake_TEST_FindPython_Conda) add_subdirectory(FindPython) endif() diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt index 10c98c5..5e20dd3 100644 --- a/Tests/FindPython/CMakeLists.txt +++ b/Tests/FindPython/CMakeLists.txt @@ -172,3 +172,16 @@ if(CMake_TEST_FindPython_NumPy) --test-command ${CMAKE_CTEST_COMMAND} -V -C $ ) endif() + + if(CMake_TEST_FindPython_Conda) + add_test(NAME FindPython.VirtualEnvConda COMMAND + ${CMAKE_CTEST_COMMAND} -C $ + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/VirtualEnvConda" + "${CMake_BINARY_DIR}/Tests/FindPython/VirtualEnvConda" + ${build_generator_args} + --build-project TestVirtualEnvConda + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $ + ) + endif() diff --git a/Tests/FindPython/VirtualEnv/CMakeLists.txt b/Tests/FindPython/VirtualEnv/CMakeLists.txt index 64ba201..9e8c673 100644 --- a/Tests/FindPython/VirtualEnv/CMakeLists.txt +++ b/Tests/FindPython/VirtualEnv/CMakeLists.txt @@ -21,22 +21,26 @@ endif() add_test(NAME FindPython3.VirtualEnvDefault COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME + --unset=CONDA_PREFIX "VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvDefault.cmake") add_test(NAME FindPython3.VirtualEnvOnly COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME + --unset=CONDA_PREFIX "VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake") add_test(NAME FindPython3.UnsetVirtualEnvOnly COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME --unset=VIRTUAL_ENV + --unset=CONDA_PREFIX "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake") add_test(NAME FindPython3.VirtualEnvStandard COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME + --unset=CONDA_PREFIX "VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvStandard.cmake") diff --git a/Tests/FindPython/VirtualEnvConda/CMakeLists.txt b/Tests/FindPython/VirtualEnvConda/CMakeLists.txt new file mode 100644 index 0000000..565095a --- /dev/null +++ b/Tests/FindPython/VirtualEnvConda/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.1) + +project(TestVirtualEnvConda LANGUAGES NONE) + +include(CTest) + +find_program(CONDA_EXECUTABLE conda) +if (CONDA_EXECUTABLE EQUAL NOTFOUND) + message (FATAL_ERROR "Fail to found Conda") +endif() + +set (Python3_VIRTUAL_ENV "${CMAKE_CURRENT_BINARY_DIR}/condaenv") + +execute_process (COMMAND "${CONDA_EXECUTABLE}" create --no-default-packages --prefix "${Python3_VIRTUAL_ENV}" --yes python=3 + RESULT_VARIABLE result + OUTPUT_VARIABLE outputs + ERROR_VARIABLE outputs) +if (result) + message (FATAL_ERROR "Fail to create virtual environment: ${outputs}") +endif() + +add_test(NAME FindPython3.VirtualEnvDefaultConda + COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME + --unset=VIRTUAL_ENV + "CONDA_PREFIX=${Python3_VIRTUAL_ENV}" + "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" + -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvDefault.cmake") + +add_test(NAME FindPython3.VirtualEnvOnlyConda + COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME + --unset=VIRTUAL_ENV + "CONDA_PREFIX=${Python3_VIRTUAL_ENV}" + "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" + -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake") +add_test(NAME FindPython3.UnsetVirtualEnvOnlyConda + COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME + --unset=CONDA_PREFIX + --unset=VIRTUAL_ENV + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake") + +add_test(NAME FindPython3.VirtualEnvStandardConda + COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME + --unset=VIRTUAL_ENV + "CONDA_PREFIX=${Python3_VIRTUAL_ENV}" + "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}" + -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvStandard.cmake") diff --git a/Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake b/Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake new file mode 100644 index 0000000..020ecac --- /dev/null +++ b/Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake @@ -0,0 +1,6 @@ + +find_package (Python3 REQUIRED) + +if (NOT Python3_EXECUTABLE MATCHES "^${PYTHON3_VIRTUAL_ENV}/.+") + message (FATAL_ERROR "Fail to use virtual environment") +endif() diff --git a/Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake b/Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake new file mode 100644 index 0000000..29a4924 --- /dev/null +++ b/Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake @@ -0,0 +1,16 @@ + +# +# Virtual environment is defined for python3 +# Trying to find a python2 using only virtual environment +# It is expecting to fail if a virtual environment is active and to success otherwise. +# +set (Python2_FIND_VIRTUALENV ONLY) +find_package (Python2 QUIET) + +if (PYTHON3_VIRTUAL_ENV AND Python2_FOUND) + message (FATAL_ERROR "Python2 unexpectedly found.") +endif() + +if (NOT PYTHON3_VIRTUAL_ENV AND NOT Python2_FOUND) + message (FATAL_ERROR "Fail to find Python2.") +endif() diff --git a/Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake b/Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake new file mode 100644 index 0000000..89f27d8 --- /dev/null +++ b/Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake @@ -0,0 +1,7 @@ + +set (Python3_FIND_VIRTUALENV STANDARD) +find_package (Python3 REQUIRED) + +if (Python3_EXECUTABLE MATCHES "^${PYTHON3_VIRTUAL_ENV}/.+") + message (FATAL_ERROR "Python3 virtual env unexpectedly found.") +endif() -- cgit v0.12