Blame view

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