diff --git a/Modules/FindLibPython.py b/Modules/FindLibPython.py new file mode 100644 index 00000000000..d4384da4eee --- /dev/null +++ b/Modules/FindLibPython.py @@ -0,0 +1,25 @@ +# Note by Nikolaus Demmel 28.03.2014: My contributions are licensend under the +# same as CMake (BSD). My adaptations are in part based +# https://github.com/qgis/QGIS/tree/master/cmake which has the following +# copyright note: + +# FindLibPython.py +# Copyright (c) 2007, Simon Edwards +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +import sys +import distutils.sysconfig + +print("exec_prefix:%s" % sys.exec_prefix) +print("major_version:%s" % str(sys.version_info[0])) +print("minor_version:%s" % str(sys.version_info[1])) +print("patch_version:%s" % str(sys.version_info[2])) +print("short_version:%s" % '.'.join(map(lambda x:str(x), sys.version_info[0:2]))) +print("long_version:%s" % '.'.join(map(lambda x:str(x), sys.version_info[0:3]))) +print("py_inc_dir:%s" % distutils.sysconfig.get_python_inc()) +print("site_packages_dir:%s" % distutils.sysconfig.get_python_lib(plat_specific=1)) +for e in distutils.sysconfig.get_config_vars ('LIBDIR'): + if e != None: + print("py_lib_dir:%s" % e) + break diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake index 1dbc9674f9b..2334ce99be1 100644 --- a/Modules/FindPythonLibs.cmake +++ b/Modules/FindPythonLibs.cmake @@ -45,129 +45,208 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake) -# Search for the python framework on Apple. -CMAKE_FIND_FRAMEWORKS(Python) +# Note by Nikolaus Demmel 28.03.2014: My contributions are licensend under the +# same as CMake (BSD). My adaptations are in part based +# https://github.com/qgis/QGIS/tree/master/cmake which has the following +# copyright note: -set(_PYTHON1_VERSIONS 1.6 1.5) -set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -set(_PYTHON3_VERSIONS 3.4 3.3 3.2 3.1 3.0) +# Copyright (c) 2007, Simon Edwards +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -if(PythonLibs_FIND_VERSION) + +if(NOT DEFINED PYTHON_INCLUDE_DIR) + if(DEFINED PYTHON_INCLUDE_PATH) + # For backward compatibility, repect PYTHON_INCLUDE_PATH. + set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH + "Path to where Python.h is found" FORCE) + else() + set(PYTHON_INCLUDE_DIR "" CACHE PATH + "Path to where Python.h is found" FORCE) + endif() +endif() + +if(EXISTS "${PYTHON_INCLUDE_DIR}" AND EXISTS "${PYTHON_LIBRARY}") + if(EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h") + file(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" _PYTHON_VERSION_STR + REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") + string(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" + PYTHONLIBS_VERSION_STRING "${_PYTHON_VERSION_STR}") + unset(_PYTHON_VERSION_STR) + endif() +else() + set(_PYTHON1_VERSIONS 1.6 1.5) + set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) + set(_PYTHON3_VERSIONS 3.4 3.3 3.2 3.1 3.0) + + unset(_PYTHON_FIND_OTHER_VERSIONS) + if(PythonLibs_FIND_VERSION) if(PythonLibs_FIND_VERSION_COUNT GREATER 1) - set(_PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION_MAJOR}.${PythonLibs_FIND_VERSION_MINOR}") - unset(_PYTHON_FIND_OTHER_VERSIONS) - if(PythonLibs_FIND_VERSION_EXACT) - if(_PYTHON_FIND_MAJ_MIN STREQUAL PythonLibs_FIND_VERSION) - set(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}") - else() - set(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}" "${_PYTHON_FIND_MAJ_MIN}") + set(_PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION_MAJOR}.${PythonLibs_FIND_VERSION_MINOR}") + if(NOT PythonLibs_FIND_VERSION_EXACT) + foreach(_PYTHON_V ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS}) + if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) + if(NOT _PYTHON_V STREQUAL PythonLibs_FIND_VERSION) + list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) endif() - else() - foreach(_PYTHON_V ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS}) - if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) - list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) - endif() - endforeach() - endif() - unset(_PYTHON_FIND_MAJ_MIN) + endif() + endforeach() + endif() + unset(_PYTHON_FIND_MAJ_MIN) else() - set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS}) + set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS}) endif() -else() + else() + # add an empty version to check the `python` executable first in case no version is requested set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS}) -endif() - -# Set up the versions we know about, in the order we will search. Always add -# the user supplied additional versions to the front. -set(_Python_VERSIONS - ${Python_ADDITIONAL_VERSIONS} - ${_PYTHON_FIND_OTHER_VERSIONS} - ) - -unset(_PYTHON_FIND_OTHER_VERSIONS) -unset(_PYTHON1_VERSIONS) -unset(_PYTHON2_VERSIONS) -unset(_PYTHON3_VERSIONS) - -foreach(_CURRENT_VERSION ${_Python_VERSIONS}) - string(REPLACE "." "" _CURRENT_VERSION_NO_DOTS ${_CURRENT_VERSION}) - if(WIN32) - find_library(PYTHON_DEBUG_LIBRARY - NAMES python${_CURRENT_VERSION_NO_DOTS}_d python - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - ) endif() - find_library(PYTHON_LIBRARY - NAMES - python${_CURRENT_VERSION_NO_DOTS} - python${_CURRENT_VERSION}mu - python${_CURRENT_VERSION}m - python${_CURRENT_VERSION}u - python${_CURRENT_VERSION} - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs - # Avoid finding the .dll in the PATH. We want the .lib. - NO_SYSTEM_ENVIRONMENT_PATH - ) - # Look for the static library in the Python config directory - find_library(PYTHON_LIBRARY - NAMES python${_CURRENT_VERSION_NO_DOTS} python${_CURRENT_VERSION} - # Avoid finding the .dll in the PATH. We want the .lib. - NO_SYSTEM_ENVIRONMENT_PATH - # This is where the static library is usually located - PATH_SUFFIXES python${_CURRENT_VERSION}/config - ) - - # For backward compatibility, honour value of PYTHON_INCLUDE_PATH, if - # PYTHON_INCLUDE_DIR is not set. - if(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR) - set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH - "Path to where Python.h is found" FORCE) + unset(_PYTHON1_VERSIONS) + unset(_PYTHON2_VERSIONS) + unset(_PYTHON3_VERSIONS) + + # Set up the versions we know about, in the order we will search. Always add + # the user supplied additional versions to the front. + # If FindPythonInterp has already found the major and minor version, + # insert that version between the user supplied versions and the stock + # version list. + # If no specific version is requested or suggested by PythonInterp, always look + # for "python" executable first + set(_PYTHON_VERSIONS ${PythonLibs_FIND_VERSION} ${PythonLibs_ADDITIONAL_VERSIONS} ) + if(DEFINED PYTHON_VERSION_MAJOR AND DEFINED PYTHON_VERSION_MINOR) + list(APPEND _PYTHON_VERSIONS ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) endif() - - set(PYTHON_FRAMEWORK_INCLUDES) - if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR) - foreach(dir ${Python_FRAMEWORKS}) - set(PYTHON_FRAMEWORK_INCLUDES ${PYTHON_FRAMEWORK_INCLUDES} - ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION}) - endforeach() + if (NOT _PYTHON_VERSIONS) + set(_PYTHON_VERSIONS ";") # empty entry at the front makeing sure we search for "python" first endif() + list(APPEND _PYTHON_VERSIONS ${_PYTHON_FIND_OTHER_VERSIONS}) - find_path(PYTHON_INCLUDE_DIR - NAMES Python.h - PATHS - ${PYTHON_FRAMEWORK_INCLUDES} - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include - PATH_SUFFIXES - python${_CURRENT_VERSION}mu - python${_CURRENT_VERSION}m - python${_CURRENT_VERSION}u - python${_CURRENT_VERSION} - ) - - # For backward compatibility, set PYTHON_INCLUDE_PATH. - set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}") - - if(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h") - file(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" python_version_str - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - PYTHONLIBS_VERSION_STRING "${python_version_str}") - unset(python_version_str) - endif() + unset(_PYTHON_FIND_OTHER_VERSIONS) - if(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR) - break() + message(STATUS "Looking for versions: ${_PYTHON_VERSIONS}") + + FIND_FILE(_FIND_LIB_PYTHON_PY FindLibPython.py PATHS ${CMAKE_MODULE_PATH} ${CMAKE_ROOT}/Modules) + + if(NOT _FIND_LIB_PYTHON_PY) + message(FATAL_ERROR "Could not find required file 'FindLibPython.py'") endif() -endforeach() + + unset(PYTHONLIBS_VERSION_STRING) + foreach(_CURRENT_VERSION IN LISTS _PYTHON_VERSIONS) + + STRING(REGEX REPLACE "^([0-9]+).*$" "\\1" _VERSION_MAJOR "${_CURRENT_VERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.([0-9]+).*$" "\\1" _VERSION_MINOR "${_CURRENT_VERSION}") + + set(_PYTHON_NAMES python) + + if (_CURRENT_VERSION MATCHES "^[0-9]+.*$") + list(APPEND _PYTHON_NAMES "python${_VERSION_MAJOR}") + if (_CURRENT_VERSION MATCHES "^[0-9]+\\.[0-9].*$") + list(APPEND _PYTHON_NAMES "python${_VERSION_MAJOR}.${_VERSION_MINOR}") + endif() + endif() + + message(STATUS "Looking for python version '${_CURRENT_VERSION}' by checking executables: ${_PYTHON_NAMES}.") + + foreach(_CURRENT_PYTHON_NAME IN LISTS _PYTHON_NAMES) + + unset(_PYTHON_EXECUTABLE CACHE) + find_program(_PYTHON_EXECUTABLE ${_CURRENT_PYTHON_NAME} + PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]) + + if(_PYTHON_EXECUTABLE) + + EXECUTE_PROCESS( + COMMAND ${_PYTHON_EXECUTABLE} "${_FIND_LIB_PYTHON_PY}" + OUTPUT_VARIABLE _PYTHON_CONFIG + RESULT_VARIABLE _PYTHON_CONFIG_RESULT + ERROR_QUIET) + + if(NOT ${_PYTHON_CONFIG_RESULT} AND (NOT ${_PYTHON_CONFIG} STREQUAL "")) + STRING(REGEX REPLACE ".*\nmajor_version:([0-9]+).*$" "\\1" _PYTHON_MAJOR_VERSION ${_PYTHON_CONFIG}) + STRING(REGEX REPLACE ".*\nminor_version:([0-9]+).*$" "\\1" _PYTHON_MINOR_VERSION ${_PYTHON_CONFIG}) + STRING(REGEX REPLACE ".*\npatch_version:([0-9]+).*$" "\\1" _PYTHON_PATCH_VERSION ${_PYTHON_CONFIG}) + STRING(REGEX REPLACE ".*\nshort_version:([^\n]+).*$" "\\1" _PYTHON_SHORT_VERSION ${_PYTHON_CONFIG}) + STRING(REGEX REPLACE ".*\nlong_version:([^\n]+).*$" "\\1" _PYTHON_LONG_VERSION ${_PYTHON_CONFIG}) + STRING(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" _PYTHON_INCLUDE_DIR ${_PYTHON_CONFIG}) + STRING(REGEX REPLACE ".*\npy_lib_dir:([^\n]+).*$" "\\1" _PYTHON_LIBRARY_DIR ${_PYTHON_CONFIG}) + STRING(REGEX REPLACE ".*\nexec_prefix:(^\n+).*$" "\\1" _PYTHON_PREFIX ${_PYTHON_CONFIG}) + + if ("${_CURRENT_VERSION}" STREQUAL "" OR + "${_CURRENT_VERSION}" STREQUAL "${_PYTHON_MAJOR_VERSION}" OR + "${_CURRENT_VERSION}" STREQUAL "${_PYTHON_SHORT_VERSION}" OR + "${_CURRENT_VERSION}" STREQUAL "${_PYTHON_LONG_VERSION}") + + message(STATUS "Found executable ${_PYTHON_EXECUTABLE} with suitable version ${_PYTHON_LONG_VERSION}") + + if(NOT EXISTS "${PYTHON_INCLUDE_DIR}") + set(PYTHON_INCLUDE_DIR "${_PYTHON_INCLUDE_DIR}") + endif() + + if(NOT EXISTS "${PYTHON_LIBRARY}") + set(_PYTHON_SHORT_VERSION_NO_DOT "${_PYTHON_MAJOR_VERSION}${_PYTHON_MINOR_VERSION}") + set(_PYTHON_LIBRARY_NAMES python${_PYTHON_SHORT_VERSION} python${_PYTHON_SHORT_VERSION_NO_DOT}) + FIND_LIBRARY(PYTHON_LIBRARY + NAMES ${_PYTHON_LIBRARY_NAMES} + PATH_SUFFIXES + python${_PYTHON_SHORT_VERSION}/config + python${_PYTHON_SHORT_VERSION_NO_DOT}/config + PATHS + ${_PYTHON_LIBRARY_DIR} + ${_PYTHON_PREFIX}/lib $ + {_PYTHON_PREFIX}/libs + NO_DEFAULT_PATH) + + if(WIN32) + find_library(PYTHON_DEBUG_LIBRARY + NAMES python${_PYTHON_SHORT_VERSION_NO_DOT}_d python + PATHS + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs + ) + endif() + endif() + + set(PYTHONLIBS_VERSION_STRING ${_PYTHON_LONG_VERSION}) + if(_PYTHON_PATCH_VERSION STREQUAL "0") + # it's called "Python 2.7", not "2.7.0" + string(REGEX REPLACE "\\.0$" "" PYTHONLIBS_VERSION_STRING "${PYTHONLIBS_VERSION_STRING}") + endif() + + break() + else() + message(STATUS "Found executable ${_PYTHON_EXECUTABLE} with UNsuitable version ${_PYTHON_LONG_VERSION}") + endif() # version ok + else() + message(WARNING "Found executable ${_PYTHON_EXECUTABLE}, but could not extract version info.") + endif() # could extract config + endif() # found executable + endforeach() # python names + if (PYTHONLIBS_VERSION_STRING) + break() + endif() + endforeach() # python versions +endif() + +unset(_PYTHON_NAMES) +unset(_PYTHON_VERSIONS) +unset(_PYTHON_EXECUTABLE CACHE) +unset(_PYTHON_MAJOR_VERSION) +unset(_PYTHON_MINOR_VERSION) +unset(_PYTHON_PATCH_VERSION) +unset(_PYTHON_SHORT_VERSION) +unset(_PYTHON_LONG_VERSION) +unset(_PYTHON_LIBRARY_DIR) +unset(_PYTHON_INCLUDE_DIR) +unset(_PYTHON_PREFIX) +unset(_PYTHON_SHORT_VERSION_NO_DOT) +unset(_PYTHON_LIBRARY_NAMES) + + +# For backward compatibility, set PYTHON_INCLUDE_PATH. +set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}") mark_as_advanced( PYTHON_DEBUG_LIBRARY