fix binary package build
[profile/ivi/opencv.git] / cmake / OpenCVDetectPython.cmake
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
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(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(${library})
79           set(PYTHON_LIBRARY "${${library_env}}")
80       endif()
81       if(${include_dir})
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       find_host_package(PythonLibs "${_version_major_minor}.${_version_patch}" EXACT)
87
88       if(PYTHONLIBS_FOUND)
89         # Copy outputs
90         set(_libs_found ${PYTHONLIBS_FOUND})
91         set(_libraries ${PYTHON_LIBRARIES})
92         set(_include_path ${PYTHON_INCLUDE_PATH})
93         set(_include_dirs ${PYTHON_INCLUDE_DIRS})
94         set(_debug_libraries ${PYTHON_DEBUG_LIBRARIES})
95         set(_libs_version_string ${PYTHONLIBS_VERSION_STRING})
96         set(_debug_library ${PYTHON_DEBUG_LIBRARY})
97         set(_library ${PYTHON_LIBRARY})
98         set(_library_debug ${PYTHON_LIBRARY_DEBUG})
99         set(_library_release ${PYTHON_LIBRARY_RELEASE})
100         set(_include_dir ${PYTHON_INCLUDE_DIR})
101         set(_include_dir2 ${PYTHON_INCLUDE_DIR2})
102
103         # Clear find_host_package side effects
104         unset(PYTHONLIBS_FOUND)
105         unset(PYTHON_LIBRARIES)
106         unset(PYTHON_INCLUDE_PATH)
107         unset(PYTHON_INCLUDE_DIRS)
108         unset(PYTHON_DEBUG_LIBRARIES)
109         unset(PYTHONLIBS_VERSION_STRING)
110         unset(PYTHON_DEBUG_LIBRARY CACHE)
111         unset(PYTHON_LIBRARY)
112         unset(PYTHON_LIBRARY_DEBUG)
113         unset(PYTHON_LIBRARY_RELEASE)
114         unset(PYTHON_LIBRARY CACHE)
115         unset(PYTHON_LIBRARY_DEBUG CACHE)
116         unset(PYTHON_LIBRARY_RELEASE CACHE)
117         unset(PYTHON_INCLUDE_DIR CACHE)
118         unset(PYTHON_INCLUDE_DIR2 CACHE)
119       endif()
120     endif()
121
122     if(NOT ANDROID AND NOT IOS)
123       if(CMAKE_HOST_UNIX)
124         execute_process(COMMAND ${_executable} -c "from distutils.sysconfig import *; print(get_python_lib())"
125                         RESULT_VARIABLE _cvpy_process
126                         OUTPUT_VARIABLE _std_packages_path
127                         OUTPUT_STRIP_TRAILING_WHITESPACE)
128         if("${_std_packages_path}" MATCHES "site-packages")
129           set(_packages_path "python${_version_major_minor}/site-packages")
130         else() #debian based assumed, install to the dist-packages.
131           set(_packages_path "python${_version_major_minor}/dist-packages")
132         endif()
133         if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/${${packages_path}}")
134           set(_packages_path "lib${LIB_SUFFIX}/${_packages_path}")
135         else()
136           set(_packages_path "lib/${_packages_path}")
137         endif()
138       elseif(CMAKE_HOST_WIN32)
139         get_filename_component(_path "${_executable}" PATH)
140         file(TO_CMAKE_PATH "${_path}" _path)
141         if(NOT EXISTS "${_path}/Lib/site-packages")
142           unset(_path)
143           get_filename_component(_path "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE)
144           if(NOT _path)
145              get_filename_component(_path "[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE)
146           endif()
147           file(TO_CMAKE_PATH "${_path}" _path)
148         endif()
149         set(_packages_path "${_path}/Lib/site-packages")
150         unset(_path)
151       endif()
152
153       set(_numpy_include_dirs ${${numpy_include_dirs}})
154
155       if(NOT _numpy_include_dirs)
156         if(CMAKE_CROSSCOMPILING)
157           message(STATUS "Cannot probe for Python/Numpy support (because we are cross-compiling OpenCV)")
158           message(STATUS "If you want to enable Python/Numpy support, set the following variables:")
159           message(STATUS "  PYTHON2_INCLUDE_PATH")
160           message(STATUS "  PYTHON2_LIBRARIES")
161           message(STATUS "  PYTHON2_NUMPY_INCLUDE_DIRS")
162           message(STATUS "  PYTHON3_INCLUDE_PATH")
163           message(STATUS "  PYTHON3_LIBRARIES")
164           message(STATUS "  PYTHON3_NUMPY_INCLUDE_DIRS")
165         else()
166           # Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy
167           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()))"
168                           RESULT_VARIABLE _numpy_process
169                           OUTPUT_VARIABLE _numpy_include_dirs
170                           OUTPUT_STRIP_TRAILING_WHITESPACE)
171
172           if(NOT _numpy_process EQUAL 0)
173               unset(_numpy_include_dirs)
174           endif()
175         endif()
176       endif()
177
178       if(_numpy_include_dirs)
179         file(TO_CMAKE_PATH "${_numpy_include_dirs}" _numpy_include_dirs)
180         if(CMAKE_CROSSCOMPILING)
181           if(NOT _numpy_version)
182             set(_numpy_version "undefined - cannot be probed because of the cross-compilation")
183           endif()
184         else()
185           execute_process(COMMAND "${_executable}" -c "import numpy; print(numpy.version.version)"
186                           RESULT_VARIABLE _numpy_process
187                           OUTPUT_VARIABLE _numpy_version
188                           OUTPUT_STRIP_TRAILING_WHITESPACE)
189         endif()
190       endif()
191     endif(NOT ANDROID AND NOT IOS)
192   endif()
193
194   # Export return values
195   set(${found} "${_found}" PARENT_SCOPE)
196   set(${executable} "${_executable}" CACHE FILEPATH "Path to Python interpretor")
197   set(${version_string} "${_version_string}" PARENT_SCOPE)
198   set(${version_major} "${_version_major}" PARENT_SCOPE)
199   set(${version_minor} "${_version_minor}" PARENT_SCOPE)
200   set(${libs_found} "${_libs_found}" PARENT_SCOPE)
201   set(${libs_version_string} "${_libs_version_string}" PARENT_SCOPE)
202   set(${libraries} "${_libraries}" PARENT_SCOPE)
203   set(${library} "${_library}" CACHE FILEPATH "Path to Python library")
204   set(${debug_libraries} "${_debug_libraries}" PARENT_SCOPE)
205   set(${debug_library} "${_debug_library}" CACHE FILEPATH "Path to Python debug")
206   set(${include_path} "${_include_path}" PARENT_SCOPE)
207   set(${include_dir} "${_include_dir}" CACHE PATH "Python include dir")
208   set(${include_dir2} "${_include_dir2}" CACHE PATH "Python include dir 2")
209   set(${packages_path} "${_packages_path}" CACHE PATH "Where to install the python packages.")
210   set(${numpy_include_dirs} ${_numpy_include_dirs} CACHE PATH "Path to numpy headers")
211   set(${numpy_version} "${_numpy_version}" PARENT_SCOPE)
212 endfunction(find_python)
213
214 find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
215     PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING
216     PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND
217     PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY
218     PYTHON2_DEBUG_LIBRARIES PYTHON2_LIBRARY_DEBUG PYTHON2_INCLUDE_PATH
219     PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH
220     PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION)
221
222 find_python(3.4 "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
223     PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING
224     PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND
225     PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY
226     PYTHON3_DEBUG_LIBRARIES PYTHON3_LIBRARY_DEBUG PYTHON3_INCLUDE_PATH
227     PYTHON3_INCLUDE_DIR PYTHON3_INCLUDE_DIR2 PYTHON3_PACKAGES_PATH
228     PYTHON3_NUMPY_INCLUDE_DIRS PYTHON3_NUMPY_VERSION)
229
230 # Use Python 2 as default Python interpreter
231 if(PYTHON2LIBS_FOUND)
232     set(PYTHON_DEFAULT_AVAILABLE "TRUE")
233     set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON2_EXECUTABLE}")
234 endif()
235
236 unset(HAVE_SPHINX CACHE)
237
238 if(BUILD_DOCS)
239   find_host_program(SPHINX_BUILD sphinx-build)
240   find_host_program(PLANTUML plantuml)
241   if(SPHINX_BUILD)
242       execute_process(COMMAND "${SPHINX_BUILD}"
243                       OUTPUT_QUIET
244                       ERROR_VARIABLE SPHINX_OUTPUT
245                       OUTPUT_STRIP_TRAILING_WHITESPACE)
246       if(SPHINX_OUTPUT MATCHES "Sphinx v([0-9][^ \n]*)")
247         set(SPHINX_VERSION "${CMAKE_MATCH_1}")
248         set(HAVE_SPHINX 1)
249         message(STATUS "Found Sphinx ${SPHINX_VERSION}: ${SPHINX_BUILD}")
250       endif()
251   endif()
252 endif(BUILD_DOCS)