1# Find specified Python version 2# Arguments: 3# preferred_version (value): Version to check for first 4# min_version (value): Minimum supported version 5# library_env (value): Name of Python library ENV variable to check 6# include_dir_env (value): Name of Python include directory ENV variable to check 7# found (variable): Set if interpreter found 8# executable (variable): Output of executable found 9# version_string (variable): Output of found version 10# version_major (variable): Output of found major version 11# version_minor (variable): Output of found minor version 12# libs_found (variable): Set if libs found 13# libs_version_string (variable): Output of found libs version 14# libraries (variable): Output of found Python libraries 15# library (variable): Output of found Python library 16# debug_libraries (variable): Output of found Python debug libraries 17# debug_library (variable): Output of found Python debug library 18# include_path (variable): Output of found Python include path 19# include_dir (variable): Output of found Python include dir 20# include_dir2 (variable): Output of found Python include dir2 21# packages_path (variable): Output of found Python packages path 22# numpy_include_dirs (variable): Output of found Python Numpy include dirs 23# numpy_version (variable): Output of found Python Numpy version 24function(find_python preferred_version min_version library_env include_dir_env 25 found executable version_string version_major version_minor 26 libs_found libs_version_string libraries library debug_libraries 27 debug_library include_path include_dir include_dir2 packages_path 28 numpy_include_dirs numpy_version) 29 30 ocv_check_environment_variables(${executable}) 31 if(${executable}) 32 set(PYTHON_EXECUTABLE "${${executable}}") 33 endif() 34 35 if(WIN32 AND NOT ${executable}) 36 # search for executable with the same bitness as resulting binaries 37 # standard FindPythonInterp always prefers executable from system path 38 # this is really important because we are using the interpreter for numpy search and for choosing the install location 39 foreach(_CURRENT_VERSION ${Python_ADDITIONAL_VERSIONS} "${preferred_version}" "${min_version}") 40 find_host_program(PYTHON_EXECUTABLE 41 NAMES python${_CURRENT_VERSION} python 42 PATHS 43 [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath] 44 [HKEY_CURRENT_USER\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath] 45 NO_SYSTEM_ENVIRONMENT_PATH 46 ) 47 endforeach() 48 endif() 49 50 find_host_package(PythonInterp "${preferred_version}") 51 if(NOT PYTHONINTERP_FOUND) 52 find_host_package(PythonInterp "${min_version}") 53 endif() 54 55 if(PYTHONINTERP_FOUND) 56 # Copy outputs 57 set(_found ${PYTHONINTERP_FOUND}) 58 set(_executable ${PYTHON_EXECUTABLE}) 59 set(_version_string ${PYTHON_VERSION_STRING}) 60 set(_version_major ${PYTHON_VERSION_MAJOR}) 61 set(_version_minor ${PYTHON_VERSION_MINOR}) 62 set(_version_patch ${PYTHON_VERSION_PATCH}) 63 64 # Clear find_host_package side effects 65 unset(PYTHONINTERP_FOUND) 66 unset(PYTHON_EXECUTABLE CACHE) 67 unset(PYTHON_VERSION_STRING) 68 unset(PYTHON_VERSION_MAJOR) 69 unset(PYTHON_VERSION_MINOR) 70 unset(PYTHON_VERSION_PATCH) 71 endif() 72 73 if(_found) 74 set(_version_major_minor "${_version_major}.${_version_minor}") 75 76 if(NOT ANDROID AND NOT IOS) 77 ocv_check_environment_variables(${library_env} ${include_dir_env}) 78 if(NOT ${${library_env}} EQUAL "") 79 set(PYTHON_LIBRARY "${${library_env}}") 80 endif() 81 if(NOT ${${include_dir_env}} EQUAL "") 82 set(PYTHON_INCLUDE_DIR "${${include_dir_env}}") 83 endif() 84 85 # not using _version_string here, because it might not conform to the CMake version format 86 if(CMAKE_CROSSCOMPILING) 87 # builder version can differ from target, matching base version (e.g. 2.7) 88 find_host_package(PythonLibs "${_version_major_minor}") 89 else() 90 find_host_package(PythonLibs "${_version_major_minor}.${_version_patch}" EXACT) 91 endif() 92 93 if(PYTHONLIBS_FOUND) 94 # Copy outputs 95 set(_libs_found ${PYTHONLIBS_FOUND}) 96 set(_libraries ${PYTHON_LIBRARIES}) 97 set(_include_path ${PYTHON_INCLUDE_PATH}) 98 set(_include_dirs ${PYTHON_INCLUDE_DIRS}) 99 set(_debug_libraries ${PYTHON_DEBUG_LIBRARIES}) 100 set(_libs_version_string ${PYTHONLIBS_VERSION_STRING}) 101 set(_debug_library ${PYTHON_DEBUG_LIBRARY}) 102 set(_library ${PYTHON_LIBRARY}) 103 set(_library_debug ${PYTHON_LIBRARY_DEBUG}) 104 set(_library_release ${PYTHON_LIBRARY_RELEASE}) 105 set(_include_dir ${PYTHON_INCLUDE_DIR}) 106 set(_include_dir2 ${PYTHON_INCLUDE_DIR2}) 107 108 # Clear find_host_package side effects 109 unset(PYTHONLIBS_FOUND) 110 unset(PYTHON_LIBRARIES) 111 unset(PYTHON_INCLUDE_PATH) 112 unset(PYTHON_INCLUDE_DIRS) 113 unset(PYTHON_DEBUG_LIBRARIES) 114 unset(PYTHONLIBS_VERSION_STRING) 115 unset(PYTHON_DEBUG_LIBRARY CACHE) 116 unset(PYTHON_LIBRARY) 117 unset(PYTHON_LIBRARY_DEBUG) 118 unset(PYTHON_LIBRARY_RELEASE) 119 unset(PYTHON_LIBRARY CACHE) 120 unset(PYTHON_LIBRARY_DEBUG CACHE) 121 unset(PYTHON_LIBRARY_RELEASE CACHE) 122 unset(PYTHON_INCLUDE_DIR CACHE) 123 unset(PYTHON_INCLUDE_DIR2 CACHE) 124 endif() 125 endif() 126 127 if(NOT ANDROID AND NOT IOS) 128 if(CMAKE_HOST_UNIX) 129 execute_process(COMMAND ${_executable} -c "from distutils.sysconfig import *; print(get_python_lib())" 130 RESULT_VARIABLE _cvpy_process 131 OUTPUT_VARIABLE _std_packages_path 132 OUTPUT_STRIP_TRAILING_WHITESPACE) 133 if("${_std_packages_path}" MATCHES "site-packages") 134 set(_packages_path "python${_version_major_minor}/site-packages") 135 else() #debian based assumed, install to the dist-packages. 136 set(_packages_path "python${_version_major_minor}/dist-packages") 137 endif() 138 if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/${${packages_path}}") 139 set(_packages_path "lib${LIB_SUFFIX}/${_packages_path}") 140 else() 141 set(_packages_path "lib/${_packages_path}") 142 endif() 143 elseif(CMAKE_HOST_WIN32) 144 get_filename_component(_path "${_executable}" PATH) 145 file(TO_CMAKE_PATH "${_path}" _path) 146 if(NOT EXISTS "${_path}/Lib/site-packages") 147 unset(_path) 148 get_filename_component(_path "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE) 149 if(NOT _path) 150 get_filename_component(_path "[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE) 151 endif() 152 file(TO_CMAKE_PATH "${_path}" _path) 153 endif() 154 set(_packages_path "${_path}/Lib/site-packages") 155 unset(_path) 156 endif() 157 158 set(_numpy_include_dirs ${${numpy_include_dirs}}) 159 160 if(NOT _numpy_include_dirs) 161 if(CMAKE_CROSSCOMPILING) 162 message(STATUS "Cannot probe for Python/Numpy support (because we are cross-compiling OpenCV)") 163 message(STATUS "If you want to enable Python/Numpy support, set the following variables:") 164 message(STATUS " PYTHON2_INCLUDE_PATH") 165 message(STATUS " PYTHON2_LIBRARIES") 166 message(STATUS " PYTHON2_NUMPY_INCLUDE_DIRS") 167 message(STATUS " PYTHON3_INCLUDE_PATH") 168 message(STATUS " PYTHON3_LIBRARIES") 169 message(STATUS " PYTHON3_NUMPY_INCLUDE_DIRS") 170 else() 171 # Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy 172 execute_process(COMMAND "${_executable}" -c "import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print(os.pathsep.join(numpy.distutils.misc_util.get_numpy_include_dirs()))" 173 RESULT_VARIABLE _numpy_process 174 OUTPUT_VARIABLE _numpy_include_dirs 175 OUTPUT_STRIP_TRAILING_WHITESPACE) 176 177 if(NOT _numpy_process EQUAL 0) 178 unset(_numpy_include_dirs) 179 endif() 180 endif() 181 endif() 182 183 if(_numpy_include_dirs) 184 file(TO_CMAKE_PATH "${_numpy_include_dirs}" _numpy_include_dirs) 185 if(CMAKE_CROSSCOMPILING) 186 if(NOT _numpy_version) 187 set(_numpy_version "undefined - cannot be probed because of the cross-compilation") 188 endif() 189 else() 190 execute_process(COMMAND "${_executable}" -c "import numpy; print(numpy.version.version)" 191 RESULT_VARIABLE _numpy_process 192 OUTPUT_VARIABLE _numpy_version 193 OUTPUT_STRIP_TRAILING_WHITESPACE) 194 endif() 195 endif() 196 endif(NOT ANDROID AND NOT IOS) 197 endif() 198 199 # Export return values 200 set(${found} "${_found}" PARENT_SCOPE) 201 set(${executable} "${_executable}" CACHE FILEPATH "Path to Python interpretor") 202 set(${version_string} "${_version_string}" PARENT_SCOPE) 203 set(${version_major} "${_version_major}" PARENT_SCOPE) 204 set(${version_minor} "${_version_minor}" PARENT_SCOPE) 205 set(${libs_found} "${_libs_found}" PARENT_SCOPE) 206 set(${libs_version_string} "${_libs_version_string}" PARENT_SCOPE) 207 set(${libraries} "${_libraries}" PARENT_SCOPE) 208 set(${library} "${_library}" CACHE FILEPATH "Path to Python library") 209 set(${debug_libraries} "${_debug_libraries}" PARENT_SCOPE) 210 set(${debug_library} "${_debug_library}" CACHE FILEPATH "Path to Python debug") 211 set(${include_path} "${_include_path}" PARENT_SCOPE) 212 set(${include_dir} "${_include_dir}" CACHE PATH "Python include dir") 213 set(${include_dir2} "${_include_dir2}" CACHE PATH "Python include dir 2") 214 set(${packages_path} "${_packages_path}" CACHE PATH "Where to install the python packages.") 215 set(${numpy_include_dirs} ${_numpy_include_dirs} CACHE PATH "Path to numpy headers") 216 set(${numpy_version} "${_numpy_version}" PARENT_SCOPE) 217endfunction(find_python) 218 219find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR 220 PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING 221 PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND 222 PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY 223 PYTHON2_DEBUG_LIBRARIES PYTHON2_LIBRARY_DEBUG PYTHON2_INCLUDE_PATH 224 PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH 225 PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION) 226 227find_python(3.4 "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR 228 PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING 229 PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND 230 PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY 231 PYTHON3_DEBUG_LIBRARIES PYTHON3_LIBRARY_DEBUG PYTHON3_INCLUDE_PATH 232 PYTHON3_INCLUDE_DIR PYTHON3_INCLUDE_DIR2 PYTHON3_PACKAGES_PATH 233 PYTHON3_NUMPY_INCLUDE_DIRS PYTHON3_NUMPY_VERSION) 234 235# Use Python 2 as default Python interpreter 236if(PYTHON2INTERP_FOUND) 237 set(PYTHON_DEFAULT_AVAILABLE "TRUE") 238 set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON2_EXECUTABLE}") 239endif() 240