Home | History | Annotate | Download | only in 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(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)
    217 endfunction(find_python)
    218 
    219 find_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 
    227 find_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
    236 if(PYTHON2INTERP_FOUND)
    237     set(PYTHON_DEFAULT_AVAILABLE "TRUE")
    238     set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON2_EXECUTABLE}")
    239 endif()
    240