OpenCVDetectPython.cmake 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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
  24. function(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. if(NOT ${found})
  30. if(" ${executable}" STREQUAL " PYTHON_EXECUTABLE")
  31. set(__update_python_vars 0)
  32. else()
  33. set(__update_python_vars 1)
  34. endif()
  35. ocv_check_environment_variables(${executable})
  36. if(${executable})
  37. set(PYTHON_EXECUTABLE "${${executable}}")
  38. endif()
  39. if(WIN32 AND NOT ${executable} AND OPENCV_PYTHON_PREFER_WIN32_REGISTRY) # deprecated
  40. # search for executable with the same bitness as resulting binaries
  41. # standard FindPythonInterp always prefers executable from system path
  42. # this is really important because we are using the interpreter for numpy search and for choosing the install location
  43. foreach(_CURRENT_VERSION ${Python_ADDITIONAL_VERSIONS} "${preferred_version}" "${min_version}")
  44. find_host_program(PYTHON_EXECUTABLE
  45. NAMES python${_CURRENT_VERSION} python
  46. PATHS
  47. [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath]
  48. [HKEY_CURRENT_USER\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath]
  49. NO_SYSTEM_ENVIRONMENT_PATH
  50. )
  51. endforeach()
  52. endif()
  53. if(preferred_version)
  54. set(__python_package_version "${preferred_version} EXACT")
  55. find_host_package(PythonInterp "${preferred_version}" EXACT)
  56. if(NOT PYTHONINTERP_FOUND)
  57. message(STATUS "Python is not found: ${preferred_version} EXACT")
  58. endif()
  59. elseif(min_version)
  60. set(__python_package_version "${min_version}")
  61. find_host_package(PythonInterp "${min_version}")
  62. else()
  63. set(__python_package_version "")
  64. find_host_package(PythonInterp)
  65. endif()
  66. string(REGEX MATCH "^[0-9]+" _python_version_major "${min_version}")
  67. if(PYTHONINTERP_FOUND)
  68. # Check if python major version is correct
  69. if(" ${_python_version_major}" STREQUAL " ")
  70. set(_python_version_major "${PYTHON_VERSION_MAJOR}")
  71. endif()
  72. if(NOT "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}"
  73. AND NOT DEFINED ${executable}
  74. )
  75. if(NOT OPENCV_SKIP_PYTHON_WARNING)
  76. message(WARNING "CMake's 'find_host_package(PythonInterp ${__python_package_version})' found wrong Python version:\n"
  77. "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\n"
  78. "PYTHON_VERSION_STRING=${PYTHON_VERSION_STRING}\n"
  79. "Consider providing the '${executable}' variable via CMake command line or environment variables\n")
  80. endif()
  81. ocv_clear_vars(PYTHONINTERP_FOUND PYTHON_EXECUTABLE PYTHON_VERSION_STRING PYTHON_VERSION_MAJOR PYTHON_VERSION_MINOR PYTHON_VERSION_PATCH)
  82. if(NOT CMAKE_VERSION VERSION_LESS "3.12")
  83. if(_python_version_major STREQUAL "2")
  84. set(__PYTHON_PREFIX Python2)
  85. else()
  86. set(__PYTHON_PREFIX Python3)
  87. endif()
  88. find_host_package(${__PYTHON_PREFIX} "${preferred_version}" COMPONENTS Interpreter)
  89. if(${__PYTHON_PREFIX}_EXECUTABLE)
  90. set(PYTHON_EXECUTABLE "${${__PYTHON_PREFIX}_EXECUTABLE}")
  91. find_host_package(PythonInterp "${preferred_version}") # Populate other variables
  92. endif()
  93. else()
  94. message(STATUS "Consider using CMake 3.12+ for better Python support")
  95. endif()
  96. endif()
  97. if(PYTHONINTERP_FOUND AND "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}")
  98. # Copy outputs
  99. set(_found ${PYTHONINTERP_FOUND})
  100. set(_executable ${PYTHON_EXECUTABLE})
  101. set(_version_string ${PYTHON_VERSION_STRING})
  102. set(_version_major ${PYTHON_VERSION_MAJOR})
  103. set(_version_minor ${PYTHON_VERSION_MINOR})
  104. set(_version_patch ${PYTHON_VERSION_PATCH})
  105. endif()
  106. endif()
  107. if(__update_python_vars)
  108. # Clear find_host_package side effects
  109. unset(PYTHONINTERP_FOUND)
  110. unset(PYTHON_EXECUTABLE CACHE)
  111. unset(PYTHON_VERSION_STRING)
  112. unset(PYTHON_VERSION_MAJOR)
  113. unset(PYTHON_VERSION_MINOR)
  114. unset(PYTHON_VERSION_PATCH)
  115. endif()
  116. if(_found)
  117. set(_version_major_minor "${_version_major}.${_version_minor}")
  118. if(NOT ANDROID AND NOT APPLE_FRAMEWORK)
  119. ocv_check_environment_variables(${library_env} ${include_dir_env})
  120. if(NOT ${${library_env}} STREQUAL "")
  121. set(PYTHON_LIBRARY "${${library_env}}")
  122. endif()
  123. if(NOT ${${include_dir_env}} STREQUAL "")
  124. set(PYTHON_INCLUDE_DIR "${${include_dir_env}}")
  125. endif()
  126. # not using _version_string here, because it might not conform to the CMake version format
  127. if(CMAKE_CROSSCOMPILING)
  128. # builder version can differ from target, matching base version (e.g. 2.7)
  129. find_package(PythonLibs "${_version_major_minor}")
  130. else()
  131. find_package(PythonLibs "${_version_major_minor}.${_version_patch}" EXACT)
  132. endif()
  133. if(PYTHONLIBS_FOUND)
  134. # Copy outputs
  135. set(_libs_found ${PYTHONLIBS_FOUND})
  136. set(_libraries ${PYTHON_LIBRARIES})
  137. set(_include_path ${PYTHON_INCLUDE_PATH})
  138. set(_include_dirs ${PYTHON_INCLUDE_DIRS})
  139. set(_debug_libraries ${PYTHON_DEBUG_LIBRARIES})
  140. set(_libs_version_string ${PYTHONLIBS_VERSION_STRING})
  141. set(_debug_library ${PYTHON_DEBUG_LIBRARY})
  142. set(_library ${PYTHON_LIBRARY})
  143. set(_library_debug ${PYTHON_LIBRARY_DEBUG})
  144. set(_library_release ${PYTHON_LIBRARY_RELEASE})
  145. set(_include_dir ${PYTHON_INCLUDE_DIR})
  146. set(_include_dir2 ${PYTHON_INCLUDE_DIR2})
  147. endif()
  148. if(__update_python_vars)
  149. # Clear find_package side effects
  150. unset(PYTHONLIBS_FOUND)
  151. unset(PYTHON_LIBRARIES)
  152. unset(PYTHON_INCLUDE_PATH)
  153. unset(PYTHON_INCLUDE_DIRS)
  154. unset(PYTHON_DEBUG_LIBRARIES)
  155. unset(PYTHONLIBS_VERSION_STRING)
  156. unset(PYTHON_DEBUG_LIBRARY CACHE)
  157. unset(PYTHON_LIBRARY)
  158. unset(PYTHON_LIBRARY_DEBUG)
  159. unset(PYTHON_LIBRARY_RELEASE)
  160. unset(PYTHON_LIBRARY CACHE)
  161. unset(PYTHON_LIBRARY_DEBUG CACHE)
  162. unset(PYTHON_LIBRARY_RELEASE CACHE)
  163. unset(PYTHON_INCLUDE_DIR CACHE)
  164. unset(PYTHON_INCLUDE_DIR2 CACHE)
  165. endif()
  166. endif()
  167. if(NOT ANDROID AND NOT IOS)
  168. if(CMAKE_HOST_UNIX)
  169. execute_process(COMMAND ${_executable} -c "from sysconfig import *; print(get_path('purelib'))"
  170. RESULT_VARIABLE _cvpy_process
  171. OUTPUT_VARIABLE _std_packages_path
  172. OUTPUT_STRIP_TRAILING_WHITESPACE)
  173. if("${_std_packages_path}" MATCHES "site-packages")
  174. set(_packages_path "python${_version_major_minor}/site-packages")
  175. else() #debian based assumed, install to the dist-packages.
  176. set(_packages_path "python${_version_major_minor}/dist-packages")
  177. endif()
  178. set(_packages_path "lib/${_packages_path}")
  179. elseif(CMAKE_HOST_WIN32)
  180. get_filename_component(_path "${_executable}" PATH)
  181. file(TO_CMAKE_PATH "${_path}" _path)
  182. if(NOT EXISTS "${_path}/Lib/site-packages")
  183. unset(_path)
  184. get_filename_component(_path "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE)
  185. if(NOT _path)
  186. get_filename_component(_path "[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE)
  187. endif()
  188. file(TO_CMAKE_PATH "${_path}" _path)
  189. endif()
  190. set(_packages_path "${_path}/Lib/site-packages")
  191. unset(_path)
  192. endif()
  193. set(_numpy_include_dirs "${${numpy_include_dirs}}")
  194. if(NOT _numpy_include_dirs)
  195. if(CMAKE_CROSSCOMPILING)
  196. message(STATUS "Cannot probe for Python/Numpy support (because we are cross-compiling OpenCV)")
  197. message(STATUS "If you want to enable Python/Numpy support, set the following variables:")
  198. message(STATUS " PYTHON2_INCLUDE_PATH")
  199. message(STATUS " PYTHON2_LIBRARIES (optional on Unix-like systems)")
  200. message(STATUS " PYTHON2_NUMPY_INCLUDE_DIRS")
  201. message(STATUS " PYTHON3_INCLUDE_PATH")
  202. message(STATUS " PYTHON3_LIBRARIES (optional on Unix-like systems)")
  203. message(STATUS " PYTHON3_NUMPY_INCLUDE_DIRS")
  204. else()
  205. # Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy
  206. 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()))"
  207. RESULT_VARIABLE _numpy_process
  208. OUTPUT_VARIABLE _numpy_include_dirs
  209. OUTPUT_STRIP_TRAILING_WHITESPACE)
  210. if(NOT _numpy_process EQUAL 0)
  211. unset(_numpy_include_dirs)
  212. endif()
  213. endif()
  214. endif()
  215. if(_numpy_include_dirs)
  216. file(TO_CMAKE_PATH "${_numpy_include_dirs}" _numpy_include_dirs)
  217. if(CMAKE_CROSSCOMPILING)
  218. if(NOT _numpy_version)
  219. set(_numpy_version "undefined - cannot be probed because of the cross-compilation")
  220. endif()
  221. else()
  222. execute_process(COMMAND "${_executable}" -c "import numpy; print(numpy.version.version)"
  223. RESULT_VARIABLE _numpy_process
  224. OUTPUT_VARIABLE _numpy_version
  225. OUTPUT_STRIP_TRAILING_WHITESPACE)
  226. endif()
  227. endif()
  228. endif(NOT ANDROID AND NOT IOS)
  229. endif()
  230. # Export return values
  231. set(${found} "${_found}" CACHE INTERNAL "")
  232. set(${executable} "${_executable}" CACHE FILEPATH "Path to Python interpreter")
  233. set(${version_string} "${_version_string}" CACHE INTERNAL "")
  234. set(${version_major} "${_version_major}" CACHE INTERNAL "")
  235. set(${version_minor} "${_version_minor}" CACHE INTERNAL "")
  236. set(${libs_found} "${_libs_found}" CACHE INTERNAL "")
  237. set(${libs_version_string} "${_libs_version_string}" CACHE INTERNAL "")
  238. set(${libraries} "${_libraries}" CACHE INTERNAL "Python libraries")
  239. set(${library} "${_library}" CACHE FILEPATH "Path to Python library")
  240. set(${debug_libraries} "${_debug_libraries}" CACHE INTERNAL "")
  241. set(${debug_library} "${_debug_library}" CACHE FILEPATH "Path to Python debug")
  242. set(${include_path} "${_include_path}" CACHE INTERNAL "")
  243. set(${include_dir} "${_include_dir}" CACHE PATH "Python include dir")
  244. set(${include_dir2} "${_include_dir2}" CACHE PATH "Python include dir 2")
  245. set(${packages_path} "${_packages_path}" CACHE PATH "Where to install the python packages.")
  246. set(${numpy_include_dirs} ${_numpy_include_dirs} CACHE PATH "Path to numpy headers")
  247. set(${numpy_version} "${_numpy_version}" CACHE INTERNAL "")
  248. endif()
  249. endfunction(find_python)
  250. if(OPENCV_PYTHON_SKIP_DETECTION)
  251. return()
  252. endif()
  253. find_python("" "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
  254. PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING
  255. PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND
  256. PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY
  257. PYTHON2_DEBUG_LIBRARIES PYTHON2_LIBRARY_DEBUG PYTHON2_INCLUDE_PATH
  258. PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH
  259. PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION)
  260. option(OPENCV_PYTHON3_VERSION "Python3 version" "")
  261. find_python("${OPENCV_PYTHON3_VERSION}" "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
  262. PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING
  263. PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND
  264. PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY
  265. PYTHON3_DEBUG_LIBRARIES PYTHON3_LIBRARY_DEBUG PYTHON3_INCLUDE_PATH
  266. PYTHON3_INCLUDE_DIR PYTHON3_INCLUDE_DIR2 PYTHON3_PACKAGES_PATH
  267. PYTHON3_NUMPY_INCLUDE_DIRS PYTHON3_NUMPY_VERSION)
  268. if(PYTHON_DEFAULT_EXECUTABLE)
  269. set(PYTHON_DEFAULT_AVAILABLE "TRUE")
  270. elseif(PYTHON2_EXECUTABLE AND PYTHON2INTERP_FOUND)
  271. # Use Python 2 as default Python interpreter
  272. set(PYTHON_DEFAULT_AVAILABLE "TRUE")
  273. set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON2_EXECUTABLE}")
  274. elseif(PYTHON3_EXECUTABLE AND PYTHON3INTERP_FOUND)
  275. # Use Python 3 as fallback Python interpreter (if there is no Python 2)
  276. set(PYTHON_DEFAULT_AVAILABLE "TRUE")
  277. set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON3_EXECUTABLE}")
  278. endif()
  279. if(PYTHON_DEFAULT_AVAILABLE)
  280. execute_process(COMMAND ${PYTHON_DEFAULT_EXECUTABLE} --version
  281. OUTPUT_VARIABLE PYTHON_DEFAULT_VERSION
  282. OUTPUT_STRIP_TRAILING_WHITESPACE)
  283. string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" PYTHON_DEFAULT_VERSION "${PYTHON_DEFAULT_VERSION}")
  284. endif()