FindPythonInterp.cmake
Go to the documentation of this file.
1 ##############################################################################
2 # @file FindPythonInterp.cmake
3 # @brief Find Python interpreter.
4 #
5 # @par Input variables:
6 # <table border="0">
7 # <tr>
8 # @tp @b Python_ADDITIONAL_VERSIONS @endtp
9 # <td>List of version numbers that should be taken into account when
10 # searching for Python.</td>
11 # </tr>
12 # </table>
13 #
14 # @par Output variables:
15 # <table border="0">
16 # <tr>
17 # @tp @b PYTHONINTERP_FOUND @endtp
18 # <td>Was the Python executable found.</td>
19 # </tr>
20 # <tr>
21 # @tp @b PYTHON_EXECUTABLE @endtp
22 # <td>Path to the Python interpreter.</td>
23 # </tr>
24 # <tr>
25 # @tp @b PYTHON_VERSION_STRING @endtp
26 # <td>Python version found e.g. 2.5.2.</td>
27 # </tr>
28 # <tr>
29 # @tp @b PYTHON_VERSION_MAJOR @endtp
30 # <td>Python major version found e.g. 2.</td>
31 # </tr>
32 # <tr>
33 # @tp @b PYTHON_VERSION_MINOR @endtp
34 # <td>Python minor version found e.g. 5.</td>
35 # </tr>
36 # <tr>
37 # @tp @b PYTHON_VERSION_PATCH @endtp
38 # <td>Python patch version found e.g. 2.</td>
39 # </tr>
40 # </table>
41 #
42 # @note This module has been copied from the Git repository of CMake on
43 # 4/12/2012, i.e., before the release of CMake 2.8.8. Once CMake 2.8.8
44 # or any version is available for all major platforms, consider to
45 # remove this module from the BASIS package.
46 #
47 # @ingroup CMakeFindModules
48 ##############################################################################
49 
50 #=============================================================================
51 # Copyright 2005-2010 Kitware, Inc.
52 # Copyright 2011 Bjoern Ricks <bjoern.ricks@gmail.com>
53 # Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
54 #
55 # Distributed under the OSI-approved BSD License (the "License");
56 # see accompanying file Copyright.txt for details.
57 #
58 # This software is distributed WITHOUT ANY WARRANTY; without even the
59 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
60 # See the License for more information.
61 #=============================================================================
62 # (To distribute this file outside of CMake, substitute the full
63 # License text for the above reference.)
64 
65 unset(_Python_NAMES)
66 
67 set(_PYTHON1_VERSIONS 1.6 1.5)
68 set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
69 set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0)
70 
71 if(PythonInterp_FIND_VERSION)
72  if(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
73  string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonInterp_FIND_VERSION}")
74  string(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}")
75  list(APPEND _Python_NAMES python${_PYTHON_FIND_MAJ_MIN} python${_PYTHON_FIND_MAJ})
76  unset(_PYTHON_FIND_OTHER_VERSIONS)
77  if(NOT PythonInterp_FIND_VERSION_EXACT)
78  foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS})
79  if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN)
80  list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V})
81  endif()
82  endforeach()
83  endif(NOT PythonInterp_FIND_VERSION_EXACT)
84  unset(_PYTHON_FIND_MAJ_MIN)
85  unset(_PYTHON_FIND_MAJ)
86  else(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
87  list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION})
88  set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION}_VERSIONS})
89  endif(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
90 else(PythonInterp_FIND_VERSION)
91  set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS})
92 endif(PythonInterp_FIND_VERSION)
93 
94 list(APPEND _Python_NAMES python)
95 
96 # Search for the current active python version first
97 find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES})
98 
99 # Set up the versions we know about, in the order we will search. Always add
100 # the user supplied additional versions to the front.
101 set(_Python_VERSIONS
102  ${Python_ADDITIONAL_VERSIONS}
103  ${_PYTHON_FIND_OTHER_VERSIONS}
104  )
105 
106 unset(_PYTHON_FIND_OTHER_VERSIONS)
107 unset(_PYTHON1_VERSIONS)
108 unset(_PYTHON2_VERSIONS)
109 unset(_PYTHON3_VERSIONS)
110 
111 # Search for newest python version if python executable isn't found
112 if(NOT PYTHON_EXECUTABLE)
113  foreach(_CURRENT_VERSION ${_Python_VERSIONS})
114  set(_Python_NAMES python${_CURRENT_VERSION})
115  if(WIN32)
116  list(APPEND _Python_NAMES python)
117  endif()
118  find_program(PYTHON_EXECUTABLE
119  NAMES ${_Python_NAMES}
120  PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]
121  )
122  endforeach()
123 endif()
124 
125 # determine python version string
126 if(PYTHON_EXECUTABLE)
127  execute_process(COMMAND "${PYTHON_EXECUTABLE}" -E -c
128  "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))"
129  OUTPUT_VARIABLE _VERSION
130  RESULT_VARIABLE _PYTHON_VERSION_RESULT
131  ERROR_QUIET)
132  if(NOT _PYTHON_VERSION_RESULT)
133  string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}")
134  # just to make sure as some programs (i.e. pydoc) do not return a non-zero
135  # exit code even though called with unknown option. This happened by mistake
136  # once when pydoc was specified instead of python as PYTHON_EXECUTABLE
137  if(NOT PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*")
138  message(WARNING "Version string returned by Python executable\n"
139  "\tPYTHON_EXECUTABLE = ${PYTHON_EXECUTABLE}"
140  "\tPYTHON_VERSION_STRING = ${PYTHON_VERSION_STRING}"
141  "\ndoes not match the expected format: <major>.<minor>.<patch>")
142  endif()
143  list(GET _VERSION 0 PYTHON_VERSION_MAJOR)
144  list(GET _VERSION 1 PYTHON_VERSION_MINOR)
145  list(GET _VERSION 2 PYTHON_VERSION_PATCH)
146  if(PYTHON_VERSION_PATCH EQUAL 0)
147  # it's called "Python 2.7", not "2.7.0"
148  string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}")
149  endif()
150  else()
151  # sys.version predates sys.version_info, so use that
152  execute_process(COMMAND "${PYTHON_EXECUTABLE}" -E -c "import sys; sys.stdout.write(sys.version)"
153  OUTPUT_VARIABLE _VERSION
154  RESULT_VARIABLE _PYTHON_VERSION_RESULT
155  ERROR_QUIET)
156  if(NOT _PYTHON_VERSION_RESULT)
157  string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}")
158  string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}")
159  string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}")
160  if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*")
161  string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}")
162  else()
163  set(PYTHON_VERSION_PATCH "0")
164  endif()
165  else()
166  # sys.version was first documented for Python 1.5, so assume
167  # this is older.
168  set(PYTHON_VERSION_STRING "1.4")
169  set(PYTHON_VERSION_MAJOR "1")
170  set(PYTHON_VERSION_MINOR "4")
171  set(PYTHON_VERSION_PATCH "0")
172  endif()
173  endif()
174  unset(_PYTHON_VERSION_RESULT)
175  unset(_VERSION)
176 endif(PYTHON_EXECUTABLE)
177 
178 # handle the QUIETLY and REQUIRED arguments and set PYTHONINTERP_FOUND to TRUE if
179 # all listed variables are TRUE
180 include(FindPackageHandleStandardArgs)
181 FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonInterp REQUIRED_VARS PYTHON_EXECUTABLE VERSION_VAR PYTHON_VERSION_STRING)
182 
183 mark_as_advanced(PYTHON_EXECUTABLE)
cmake _PYTHON1_VERSIONS
std::string join(const std::string &base, const std::string &path)
Join two paths, e.g., base path and relative path.
Definition: path.cxx:432
cmake _Python_NAMES
cmake _PYTHON3_VERSIONS
function match(in value, in pattern)
This function implements a more portable way to do pattern matching.
if(oldcoutbuf)
cmake PYTHON_VERSION_STRING
cmake _PYTHON2_VERSIONS