1# Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2# file Copyright.txt or https://cmake.org/licensing for details. 3 4#.rst: 5# FindPythonInterp 6# ---------------- 7# 8# Find python interpreter 9# 10# This module finds if Python interpreter is installed and determines 11# where the executables are. This code sets the following variables: 12# 13# :: 14# 15# PYTHONINTERP_FOUND - Was the Python executable found 16# PYTHON_EXECUTABLE - path to the Python interpreter 17# 18# 19# 20# :: 21# 22# PYTHON_VERSION_STRING - Python version found e.g. 2.5.2 23# PYTHON_VERSION_MAJOR - Python major version found e.g. 2 24# PYTHON_VERSION_MINOR - Python minor version found e.g. 5 25# PYTHON_VERSION_PATCH - Python patch version found e.g. 2 26# 27# 28# 29# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list 30# of version numbers that should be taken into account when searching 31# for Python. You need to set this variable before calling 32# find_package(PythonInterp). 33# 34# If calling both ``find_package(PythonInterp)`` and 35# ``find_package(PythonLibs)``, call ``find_package(PythonInterp)`` first to 36# get the currently active Python version by default with a consistent version 37# of PYTHON_LIBRARIES. 38 39function(determine_python_version exe result) 40 execute_process(COMMAND "${exe}" -c 41 "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))" 42 OUTPUT_VARIABLE _VERSION 43 RESULT_VARIABLE _PYTHON_VERSION_RESULT 44 ERROR_QUIET) 45 if(_PYTHON_VERSION_RESULT) 46 # sys.version predates sys.version_info, so use that 47 execute_process(COMMAND "${exe}" -c "import sys; sys.stdout.write(sys.version)" 48 OUTPUT_VARIABLE _VERSION 49 RESULT_VARIABLE _PYTHON_VERSION_RESULT 50 ERROR_QUIET) 51 if(_PYTHON_VERSION_RESULT) 52 # sys.version was first documented for Python 1.5, so assume 53 # this is older. 54 set(ver "1.4") 55 else() 56 string(REGEX REPLACE " .*" "" ver "${_VERSION}") 57 endif() 58 else() 59 string(REPLACE ";" "." ver "${_VERSION}") 60 endif() 61 set(${result} ${ver} PARENT_SCOPE) 62endfunction() 63 64# Find out if the 'python' executable on path has the correct version, 65# and choose it if it does. This gives this executable the highest 66# priority, which is expected behaviour. 67find_program(PYTHON_EXECUTABLE python) 68if(NOT (${PYTHON_EXECUTABLE} STREQUAL PYTHON_EXECUTABLE-NOTFOUND)) 69 determine_python_version(${PYTHON_EXECUTABLE} ver) 70 if(${ver} VERSION_LESS PythonInterp_FIND_VERSION) 71 # We didn't find the correct version on path, so forget about it 72 # and continue looking. 73 unset(PYTHON_EXECUTABLE) 74 unset(PYTHON_EXECUTABLE CACHE) 75 endif() 76endif() 77 78unset(_Python_NAMES) 79 80set(_PYTHON1_VERSIONS 1.6 1.5) 81set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) 82set(_PYTHON3_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) 83 84if(PythonInterp_FIND_VERSION) 85 if(PythonInterp_FIND_VERSION_COUNT GREATER 1) 86 set(_PYTHON_FIND_MAJ_MIN "${PythonInterp_FIND_VERSION_MAJOR}.${PythonInterp_FIND_VERSION_MINOR}") 87 list(APPEND _Python_NAMES 88 python${_PYTHON_FIND_MAJ_MIN} 89 python${PythonInterp_FIND_VERSION_MAJOR}) 90 unset(_PYTHON_FIND_OTHER_VERSIONS) 91 if(NOT PythonInterp_FIND_VERSION_EXACT) 92 foreach(_PYTHON_V ${_PYTHON${PythonInterp_FIND_VERSION_MAJOR}_VERSIONS}) 93 if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) 94 list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) 95 endif() 96 endforeach() 97 endif() 98 unset(_PYTHON_FIND_MAJ_MIN) 99 else() 100 list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION_MAJOR}) 101 set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION_MAJOR}_VERSIONS}) 102 endif() 103else() 104 set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS}) 105endif() 106find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES}) 107 108# Set up the versions we know about, in the order we will search. Always add 109# the user supplied additional versions to the front. 110set(_Python_VERSIONS ${Python_ADDITIONAL_VERSIONS}) 111# If FindPythonInterp has already found the major and minor version, 112# insert that version next to get consistent versions of the interpreter and 113# library. 114if(DEFINED PYTHONLIBS_VERSION_STRING) 115 string(REPLACE "." ";" _PYTHONLIBS_VERSION "${PYTHONLIBS_VERSION_STRING}") 116 list(GET _PYTHONLIBS_VERSION 0 _PYTHONLIBS_VERSION_MAJOR) 117 list(GET _PYTHONLIBS_VERSION 1 _PYTHONLIBS_VERSION_MINOR) 118 list(APPEND _Python_VERSIONS ${_PYTHONLIBS_VERSION_MAJOR}.${_PYTHONLIBS_VERSION_MINOR}) 119endif() 120 121# Search for the current active python version first on Linux, and last on Windows 122if(NOT WIN32) 123 list(APPEND _Python_VERSIONS ";") 124endif() 125 126list(APPEND _Python_VERSIONS ${_PYTHON_FIND_OTHER_VERSIONS}) 127 128if(WIN32) 129 list(APPEND _Python_VERSIONS ";") 130endif() 131 132unset(_PYTHON_FIND_OTHER_VERSIONS) 133unset(_PYTHON1_VERSIONS) 134unset(_PYTHON2_VERSIONS) 135unset(_PYTHON3_VERSIONS) 136 137# Search for newest python version if python executable isn't found 138if(NOT PYTHON_EXECUTABLE) 139 foreach(_CURRENT_VERSION IN LISTS _Python_VERSIONS) 140 set(_Python_NAMES python${_CURRENT_VERSION}) 141 if(WIN32) 142 list(APPEND _Python_NAMES python) 143 endif() 144 145 if(WIN32) 146 find_program(PYTHON_EXECUTABLE 147 NAMES ${_Python_NAMES} 148 HINTS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath] 149 ) 150 endif() 151 152 find_program(PYTHON_EXECUTABLE 153 NAMES ${_Python_NAMES} 154 PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath] 155 ) 156 endforeach() 157endif() 158 159# determine python version string 160if(PYTHON_EXECUTABLE) 161 determine_python_version(${PYTHON_EXECUTABLE} res) 162 set(PYTHON_VERSION_STRING ${res}) 163 164 if(PYTHON_VERSION_STRING MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") 165 set(PYTHON_VERSION_PATCH "${CMAKE_MATCH_3}") 166 else() 167 set(PYTHON_VERSION_PATCH "0") 168 endif() 169 set(PYTHON_VERSION_MAJOR "${CMAKE_MATCH_1}") 170 set(PYTHON_VERSION_MINOR "${CMAKE_MATCH_2}") 171endif() 172 173include(FindPackageHandleStandardArgs) 174FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonInterp REQUIRED_VARS PYTHON_EXECUTABLE VERSION_VAR PYTHON_VERSION_STRING) 175 176mark_as_advanced(PYTHON_EXECUTABLE) 177