FindPythonLibs.cmake 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. # - Find python libraries
  2. # This module finds if Python is installed and determines where the
  3. # include files and libraries are. It also determines what the name of
  4. # the library is. This code sets the following variables:
  5. #
  6. # PYTHONLIBS_FOUND - have the Python libs been found
  7. # PYTHON_LIBRARIES - path to the python library
  8. # PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated)
  9. # PYTHON_INCLUDE_DIRS - path to where Python.h is found
  10. # PYTHON_DEBUG_LIBRARIES - path to the debug library (deprecated)
  11. # PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8)
  12. #
  13. # The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of
  14. # version numbers that should be taken into account when searching for Python.
  15. # You need to set this variable before calling find_package(PythonLibs).
  16. #
  17. # If you'd like to specify the installation of Python to use, you should modify
  18. # the following cache variables:
  19. # PYTHON_LIBRARY - path to the python library
  20. # PYTHON_INCLUDE_DIR - path to where Python.h is found
  21. #=============================================================================
  22. # Copyright 2001-2009 Kitware, Inc.
  23. #
  24. # Distributed under the OSI-approved BSD License (the "License");
  25. # see accompanying file Copyright.txt for details.
  26. #
  27. # This software is distributed WITHOUT ANY WARRANTY; without even the
  28. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  29. # See the License for more information.
  30. #=============================================================================
  31. # (To distribute this file outside of CMake, substitute the full
  32. # License text for the above reference.)
  33. # Note by Nikolaus Demmel 28.03.2014: My contributions are licensend under the
  34. # same as CMake (BSD). My adaptations are in part based
  35. # https://github.com/qgis/QGIS/tree/master/cmake which has the following
  36. # copyright note:
  37. # Copyright (c) 2007, Simon Edwards <[email protected]>
  38. # Redistribution and use is allowed according to the terms of the BSD license.
  39. # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
  40. if(NOT DEFINED PYTHON_INCLUDE_DIR)
  41. if(DEFINED PYTHON_INCLUDE_PATH)
  42. # For backward compatibility, repect PYTHON_INCLUDE_PATH.
  43. set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH
  44. "Path to where Python.h is found" FORCE)
  45. else()
  46. set(PYTHON_INCLUDE_DIR "" CACHE PATH
  47. "Path to where Python.h is found" FORCE)
  48. endif()
  49. endif()
  50. if(EXISTS "${PYTHON_INCLUDE_DIR}" AND EXISTS "${PYTHON_LIBRARY}")
  51. if(EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h")
  52. file(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" _PYTHON_VERSION_STR
  53. REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"")
  54. string(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
  55. PYTHONLIBS_VERSION_STRING "${_PYTHON_VERSION_STR}")
  56. unset(_PYTHON_VERSION_STR)
  57. endif()
  58. else()
  59. set(_PYTHON1_VERSIONS 1.6 1.5)
  60. set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
  61. set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
  62. unset(_PYTHON_FIND_OTHER_VERSIONS)
  63. if(PythonLibs_FIND_VERSION)
  64. if(PythonLibs_FIND_VERSION_COUNT GREATER 1)
  65. set(_PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION_MAJOR}.${PythonLibs_FIND_VERSION_MINOR}")
  66. if(NOT PythonLibs_FIND_VERSION_EXACT)
  67. foreach(_PYTHON_V ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS})
  68. if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN)
  69. if(NOT _PYTHON_V STREQUAL PythonLibs_FIND_VERSION)
  70. list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V})
  71. endif()
  72. endif()
  73. endforeach()
  74. endif()
  75. unset(_PYTHON_FIND_MAJ_MIN)
  76. else()
  77. set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS})
  78. endif()
  79. else()
  80. # add an empty version to check the `python` executable first in case no version is requested
  81. set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS})
  82. endif()
  83. unset(_PYTHON1_VERSIONS)
  84. unset(_PYTHON2_VERSIONS)
  85. unset(_PYTHON3_VERSIONS)
  86. # Set up the versions we know about, in the order we will search. Always add
  87. # the user supplied additional versions to the front.
  88. # If FindPythonInterp has already found the major and minor version,
  89. # insert that version between the user supplied versions and the stock
  90. # version list.
  91. # If no specific version is requested or suggested by PythonInterp, always look
  92. # for "python" executable first
  93. set(_PYTHON_VERSIONS ${PythonLibs_FIND_VERSION} ${PythonLibs_ADDITIONAL_VERSIONS} )
  94. if(DEFINED PYTHON_VERSION_MAJOR AND DEFINED PYTHON_VERSION_MINOR)
  95. list(APPEND _PYTHON_VERSIONS ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
  96. endif()
  97. if (NOT _PYTHON_VERSIONS)
  98. set(_PYTHON_VERSIONS ";") # empty entry at the front makeing sure we search for "python" first
  99. endif()
  100. list(APPEND _PYTHON_VERSIONS ${_PYTHON_FIND_OTHER_VERSIONS})
  101. unset(_PYTHON_FIND_OTHER_VERSIONS)
  102. message(STATUS "Looking for versions: ${_PYTHON_VERSIONS}")
  103. FIND_FILE(_FIND_LIB_PYTHON_PY FindLibPython.py PATHS ${CMAKE_MODULE_PATH} ${CMAKE_ROOT}/Modules)
  104. if(NOT _FIND_LIB_PYTHON_PY)
  105. message(FATAL_ERROR "Could not find required file 'FindLibPython.py'")
  106. endif()
  107. unset(PYTHONLIBS_VERSION_STRING)
  108. foreach(_CURRENT_VERSION IN LISTS _PYTHON_VERSIONS)
  109. STRING(REGEX REPLACE "^([0-9]+).*$" "\\1" _VERSION_MAJOR "${_CURRENT_VERSION}")
  110. STRING(REGEX REPLACE "^[0-9]+\\.([0-9]+).*$" "\\1" _VERSION_MINOR "${_CURRENT_VERSION}")
  111. set(_PYTHON_NAMES ${PYTHON_EXECUTABLE} python)
  112. if (_CURRENT_VERSION MATCHES "^[0-9]+.*$")
  113. list(APPEND _PYTHON_NAMES "python${_VERSION_MAJOR}")
  114. if (_CURRENT_VERSION MATCHES "^[0-9]+\\.[0-9].*$")
  115. list(APPEND _PYTHON_NAMES "python${_VERSION_MAJOR}.${_VERSION_MINOR}")
  116. endif()
  117. endif()
  118. message(STATUS "Looking for python version '${_CURRENT_VERSION}' by checking executables: ${_PYTHON_NAMES}.")
  119. foreach(_CURRENT_PYTHON_NAME IN LISTS _PYTHON_NAMES)
  120. unset(_PYTHON_EXECUTABLE CACHE)
  121. find_program(_PYTHON_EXECUTABLE ${_CURRENT_PYTHON_NAME}
  122. PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath])
  123. if(_PYTHON_EXECUTABLE)
  124. EXECUTE_PROCESS(
  125. COMMAND ${_PYTHON_EXECUTABLE} "${_FIND_LIB_PYTHON_PY}"
  126. OUTPUT_VARIABLE _PYTHON_CONFIG
  127. RESULT_VARIABLE _PYTHON_CONFIG_RESULT
  128. ERROR_QUIET)
  129. if(NOT ${_PYTHON_CONFIG_RESULT} AND (NOT ${_PYTHON_CONFIG} STREQUAL ""))
  130. STRING(REGEX REPLACE ".*\nmajor_version:([0-9]+).*$" "\\1" _PYTHON_MAJOR_VERSION ${_PYTHON_CONFIG})
  131. STRING(REGEX REPLACE ".*\nminor_version:([0-9]+).*$" "\\1" _PYTHON_MINOR_VERSION ${_PYTHON_CONFIG})
  132. STRING(REGEX REPLACE ".*\npatch_version:([0-9]+).*$" "\\1" _PYTHON_PATCH_VERSION ${_PYTHON_CONFIG})
  133. STRING(REGEX REPLACE ".*\nshort_version:([^\n]+).*$" "\\1" _PYTHON_SHORT_VERSION ${_PYTHON_CONFIG})
  134. STRING(REGEX REPLACE ".*\nlong_version:([^\n]+).*$" "\\1" _PYTHON_LONG_VERSION ${_PYTHON_CONFIG})
  135. STRING(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" _PYTHON_INCLUDE_DIR ${_PYTHON_CONFIG})
  136. STRING(REGEX REPLACE ".*\npy_lib_dir:([^\n]+).*$" "\\1" _PYTHON_LIBRARY_DIR ${_PYTHON_CONFIG})
  137. STRING(REGEX REPLACE ".*\nexec_prefix:(^\n+).*$" "\\1" _PYTHON_PREFIX ${_PYTHON_CONFIG})
  138. if ("${_CURRENT_VERSION}" STREQUAL "" OR
  139. "${_CURRENT_VERSION}" STREQUAL "${_PYTHON_MAJOR_VERSION}" OR
  140. "${_CURRENT_VERSION}" STREQUAL "${_PYTHON_SHORT_VERSION}" OR
  141. "${_CURRENT_VERSION}" STREQUAL "${_PYTHON_LONG_VERSION}")
  142. message(STATUS "Found executable ${_PYTHON_EXECUTABLE} with suitable version ${_PYTHON_LONG_VERSION}")
  143. if(NOT EXISTS "${PYTHON_INCLUDE_DIR}")
  144. set(PYTHON_INCLUDE_DIR "${_PYTHON_INCLUDE_DIR}")
  145. endif()
  146. if(NOT EXISTS "${PYTHON_LIBRARY}")
  147. set(_PYTHON_SHORT_VERSION_NO_DOT "${_PYTHON_MAJOR_VERSION}${_PYTHON_MINOR_VERSION}")
  148. set(_PYTHON_LIBRARY_NAMES python${_PYTHON_SHORT_VERSION} python${_PYTHON_SHORT_VERSION_NO_DOT} python${_PYTHON_SHORT_VERSION}m python${_PYTHON_SHORT_VERSION_NO_DOT}m)
  149. FIND_LIBRARY(PYTHON_LIBRARY
  150. NAMES ${_PYTHON_LIBRARY_NAMES}
  151. PATH_SUFFIXES
  152. "python${_PYTHON_SHORT_VERSION}/config"
  153. "python${_PYTHON_SHORT_VERSION_NO_DOT}/config"
  154. PATHS
  155. ${_PYTHON_LIBRARY_DIR}
  156. ${_PYTHON_PREFIX}/lib
  157. ${_PYTHON_PREFIX}/libs
  158. ${_PYTHON_LIBRARY_DIR}/x86_64-linux-gnu/
  159. NO_DEFAULT_PATH)
  160. if(WIN32)
  161. find_library(PYTHON_DEBUG_LIBRARY
  162. NAMES python${_PYTHON_SHORT_VERSION_NO_DOT}_d python
  163. PATHS
  164. [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
  165. [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
  166. [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
  167. [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
  168. )
  169. endif()
  170. endif()
  171. set(PYTHONLIBS_VERSION_STRING ${_PYTHON_LONG_VERSION})
  172. if(_PYTHON_PATCH_VERSION STREQUAL "0")
  173. # it's called "Python 2.7", not "2.7.0"
  174. string(REGEX REPLACE "\\.0$" "" PYTHONLIBS_VERSION_STRING "${PYTHONLIBS_VERSION_STRING}")
  175. endif()
  176. break()
  177. else()
  178. message(STATUS "Found executable ${_PYTHON_EXECUTABLE} with UNsuitable version ${_PYTHON_LONG_VERSION}")
  179. endif() # version ok
  180. else()
  181. message(WARNING "Found executable ${_PYTHON_EXECUTABLE}, but could not extract version info.")
  182. endif() # could extract config
  183. endif() # found executable
  184. endforeach() # python names
  185. if (PYTHONLIBS_VERSION_STRING)
  186. break()
  187. endif()
  188. endforeach() # python versions
  189. endif()
  190. unset(_PYTHON_NAMES)
  191. unset(_PYTHON_VERSIONS)
  192. unset(_PYTHON_EXECUTABLE CACHE)
  193. unset(_PYTHON_MAJOR_VERSION)
  194. unset(_PYTHON_MINOR_VERSION)
  195. unset(_PYTHON_PATCH_VERSION)
  196. unset(_PYTHON_SHORT_VERSION)
  197. unset(_PYTHON_LONG_VERSION)
  198. unset(_PYTHON_LIBRARY_DIR)
  199. unset(_PYTHON_INCLUDE_DIR)
  200. unset(_PYTHON_PREFIX)
  201. unset(_PYTHON_SHORT_VERSION_NO_DOT)
  202. unset(_PYTHON_LIBRARY_NAMES)
  203. # For backward compatibility, set PYTHON_INCLUDE_PATH.
  204. set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}")
  205. mark_as_advanced(
  206. PYTHON_DEBUG_LIBRARY
  207. PYTHON_LIBRARY
  208. PYTHON_INCLUDE_DIR
  209. )
  210. # We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
  211. # cache entries because they are meant to specify the location of a single
  212. # library. We now set the variables listed by the documentation for this
  213. # module.
  214. set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
  215. set(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
  216. # These variables have been historically named in this module different from
  217. # what SELECT_LIBRARY_CONFIGURATIONS() expects.
  218. set(PYTHON_LIBRARY_DEBUG "${PYTHON_DEBUG_LIBRARY}")
  219. set(PYTHON_LIBRARY_RELEASE "${PYTHON_LIBRARY}")
  220. include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
  221. SELECT_LIBRARY_CONFIGURATIONS(PYTHON)
  222. if(PYTHON_LIBRARY AND NOT PYTHON_LIBRARIES)
  223. set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
  224. endif()
  225. # SELECT_LIBRARY_CONFIGURATIONS() sets ${PREFIX}_FOUND if it has a library.
  226. # Unset this, this prefix doesn't match the module prefix, they are different
  227. # for historical reasons.
  228. unset(PYTHON_FOUND)
  229. # include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  230. include(FindPackageHandleStandardArgs)
  231. FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs
  232. REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS
  233. VERSION_VAR PYTHONLIBS_VERSION_STRING)
  234. # PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is used to build modules for python.
  235. # PYTHON_WRITE_MODULES_HEADER(<filename>) writes a header file you can include
  236. # in your sources to initialize the static python modules
  237. function(PYTHON_ADD_MODULE _NAME )
  238. get_property(_TARGET_SUPPORTS_SHARED_LIBS
  239. GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
  240. option(PYTHON_ENABLE_MODULE_${_NAME} "Add module ${_NAME}" TRUE)
  241. option(PYTHON_MODULE_${_NAME}_BUILD_SHARED
  242. "Add module ${_NAME} shared" ${_TARGET_SUPPORTS_SHARED_LIBS})
  243. # Mark these options as advanced
  244. mark_as_advanced(PYTHON_ENABLE_MODULE_${_NAME}
  245. PYTHON_MODULE_${_NAME}_BUILD_SHARED)
  246. if(PYTHON_ENABLE_MODULE_${_NAME})
  247. if(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
  248. set(PY_MODULE_TYPE MODULE)
  249. else()
  250. set(PY_MODULE_TYPE STATIC)
  251. set_property(GLOBAL APPEND PROPERTY PY_STATIC_MODULES_LIST ${_NAME})
  252. endif()
  253. set_property(GLOBAL APPEND PROPERTY PY_MODULES_LIST ${_NAME})
  254. add_library(${_NAME} ${PY_MODULE_TYPE} ${ARGN})
  255. # target_link_libraries(${_NAME} ${PYTHON_LIBRARIES})
  256. if(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
  257. set_target_properties(${_NAME} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
  258. if(WIN32 AND NOT CYGWIN)
  259. set_target_properties(${_NAME} PROPERTIES SUFFIX ".pyd")
  260. endif()
  261. endif()
  262. endif()
  263. endfunction()
  264. function(PYTHON_WRITE_MODULES_HEADER _filename)
  265. get_property(PY_STATIC_MODULES_LIST GLOBAL PROPERTY PY_STATIC_MODULES_LIST)
  266. get_filename_component(_name "${_filename}" NAME)
  267. string(REPLACE "." "_" _name "${_name}")
  268. string(TOUPPER ${_name} _nameUpper)
  269. set(_filename ${CMAKE_CURRENT_BINARY_DIR}/${_filename})
  270. set(_filenameTmp "${_filename}.in")
  271. file(WRITE ${_filenameTmp} "/*Created by cmake, do not edit, changes will be lost*/\n")
  272. file(APPEND ${_filenameTmp}
  273. "#ifndef ${_nameUpper}
  274. #define ${_nameUpper}
  275. #include <Python.h>
  276. #ifdef __cplusplus
  277. extern \"C\" {
  278. #endif /* __cplusplus */
  279. ")
  280. foreach(_currentModule ${PY_STATIC_MODULES_LIST})
  281. file(APPEND ${_filenameTmp} "extern void init${PYTHON_MODULE_PREFIX}${_currentModule}(void);\n\n")
  282. endforeach()
  283. file(APPEND ${_filenameTmp}
  284. "#ifdef __cplusplus
  285. }
  286. #endif /* __cplusplus */
  287. ")
  288. foreach(_currentModule ${PY_STATIC_MODULES_LIST})
  289. file(APPEND ${_filenameTmp} "int ${_name}_${_currentModule}(void) \n{\n static char name[]=\"${PYTHON_MODULE_PREFIX}${_currentModule}\"; return PyImport_AppendInittab(name, init${PYTHON_MODULE_PREFIX}${_currentModule});\n}\n\n")
  290. endforeach()
  291. file(APPEND ${_filenameTmp} "void ${_name}_LoadAllPythonModules(void)\n{\n")
  292. foreach(_currentModule ${PY_STATIC_MODULES_LIST})
  293. file(APPEND ${_filenameTmp} " ${_name}_${_currentModule}();\n")
  294. endforeach()
  295. file(APPEND ${_filenameTmp} "}\n\n")
  296. file(APPEND ${_filenameTmp} "#ifndef EXCLUDE_LOAD_ALL_FUNCTION\nvoid CMakeLoadAllPythonModules(void)\n{\n ${_name}_LoadAllPythonModules();\n}\n#endif\n\n#endif\n")
  297. # with configure_file() cmake complains that you may not use a file created using file(WRITE) as input file for configure_file()
  298. execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_filenameTmp}" "${_filename}" OUTPUT_QUIET ERROR_QUIET)
  299. endfunction()