pybind11NewTools.cmake 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. # tools/pybind11NewTools.cmake -- Build system for the pybind11 modules
  2. #
  3. # Copyright (c) 2020 Wenzel Jakob <wenzel@inf.ethz.ch> and Henry Schreiner
  4. #
  5. # All rights reserved. Use of this source code is governed by a
  6. # BSD-style license that can be found in the LICENSE file.
  7. get_property(
  8. is_config
  9. TARGET pybind11::headers
  10. PROPERTY IMPORTED)
  11. if(pybind11_FIND_QUIETLY)
  12. set(_pybind11_quiet QUIET)
  13. else()
  14. set(_pybind11_quiet "")
  15. endif()
  16. if(CMAKE_VERSION VERSION_LESS 3.12)
  17. message(FATAL_ERROR "You cannot use the new FindPython module with CMake < 3.12")
  18. endif()
  19. if(NOT Python_FOUND
  20. AND NOT Python3_FOUND
  21. AND NOT Python2_FOUND)
  22. if(NOT DEFINED Python_FIND_IMPLEMENTATIONS)
  23. set(Python_FIND_IMPLEMENTATIONS CPython PyPy)
  24. endif()
  25. # GitHub Actions like activation
  26. if(NOT DEFINED Python_ROOT_DIR AND DEFINED ENV{pythonLocation})
  27. set(Python_ROOT_DIR "$ENV{pythonLocation}")
  28. endif()
  29. find_package(Python REQUIRED COMPONENTS Interpreter Development ${_pybind11_quiet})
  30. # If we are in submodule mode, export the Python targets to global targets.
  31. # If this behavior is not desired, FindPython _before_ pybind11.
  32. if(NOT is_config)
  33. set_property(TARGET Python::Python PROPERTY IMPORTED_GLOBAL TRUE)
  34. set_property(TARGET Python::Interpreter PROPERTY IMPORTED_GLOBAL TRUE)
  35. if(TARGET Python::Module)
  36. set_property(TARGET Python::Module PROPERTY IMPORTED_GLOBAL TRUE)
  37. endif()
  38. endif()
  39. endif()
  40. if(Python_FOUND)
  41. set(_Python
  42. Python
  43. CACHE INTERNAL "" FORCE)
  44. elseif(Python3_FOUND AND NOT Python2_FOUND)
  45. set(_Python
  46. Python3
  47. CACHE INTERNAL "" FORCE)
  48. elseif(Python2_FOUND AND NOT Python3_FOUND)
  49. set(_Python
  50. Python2
  51. CACHE INTERNAL "" FORCE)
  52. else()
  53. message(AUTHOR_WARNING "Python2 and Python3 both present, pybind11 in "
  54. "PYBIND11_NOPYTHON mode (manually activate to silence warning)")
  55. set(_pybind11_nopython ON)
  56. return()
  57. endif()
  58. if(PYBIND11_MASTER_PROJECT)
  59. if(${_Python}_INTERPRETER_ID MATCHES "PyPy")
  60. message(STATUS "PyPy ${${_Python}_PyPy_VERSION} (Py ${${_Python}_VERSION})")
  61. else()
  62. message(STATUS "${_Python} ${${_Python}_VERSION}")
  63. endif()
  64. endif()
  65. # If a user finds Python, they may forget to include the Interpreter component
  66. # and the following two steps require it. It is highly recommended by CMake
  67. # when finding development libraries anyway, so we will require it.
  68. if(NOT DEFINED ${_Python}_EXECUTABLE)
  69. message(
  70. FATAL_ERROR
  71. "${_Python} was found without the Interpreter component. Pybind11 requires this component.")
  72. endif()
  73. if(NOT DEFINED PYTHON_IS_DEBUG)
  74. # Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter
  75. execute_process(
  76. COMMAND "${${_Python}_EXECUTABLE}" "-c"
  77. "import sys; sys.exit(hasattr(sys, 'gettotalrefcount'))"
  78. RESULT_VARIABLE _PYTHON_IS_DEBUG)
  79. set(PYTHON_IS_DEBUG
  80. "${_PYTHON_IS_DEBUG}"
  81. CACHE INTERNAL "Python debug status")
  82. endif()
  83. # Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is
  84. # required for PyPy3 (as of 7.3.1)
  85. if(NOT DEFINED PYTHON_MODULE_EXTENSION)
  86. execute_process(
  87. COMMAND
  88. "${${_Python}_EXECUTABLE}" "-c"
  89. "from distutils import sysconfig as s;print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))"
  90. OUTPUT_VARIABLE _PYTHON_MODULE_EXTENSION
  91. ERROR_VARIABLE _PYTHON_MODULE_EXTENSION_ERR
  92. OUTPUT_STRIP_TRAILING_WHITESPACE)
  93. if(_PYTHON_MODULE_EXTENSION STREQUAL "")
  94. message(
  95. FATAL_ERROR "pybind11 could not query the module file extension, likely the 'distutils'"
  96. "package is not installed. Full error message:\n${_PYTHON_MODULE_EXTENSION_ERR}")
  97. endif()
  98. # This needs to be available for the pybind11_extension function
  99. set(PYTHON_MODULE_EXTENSION
  100. "${_PYTHON_MODULE_EXTENSION}"
  101. CACHE INTERNAL "")
  102. endif()
  103. # Python debug libraries expose slightly different objects before 3.8
  104. # https://docs.python.org/3.6/c-api/intro.html#debugging-builds
  105. # https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
  106. if(PYTHON_IS_DEBUG)
  107. set_property(
  108. TARGET pybind11::pybind11
  109. APPEND
  110. PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
  111. endif()
  112. # Check on every access - since Python2 and Python3 could have been used - do nothing in that case.
  113. if(DEFINED ${_Python}_INCLUDE_DIRS)
  114. # Only add Python for build - must be added during the import for config
  115. # since it has to be re-discovered.
  116. #
  117. # This needs to be a target to be included after the local pybind11
  118. # directory, just in case there there is an installed pybind11 sitting
  119. # next to Python's includes. It also ensures Python is a SYSTEM library.
  120. add_library(pybind11::python_headers INTERFACE IMPORTED)
  121. set_property(
  122. TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES
  123. "$<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>")
  124. set_property(
  125. TARGET pybind11::pybind11
  126. APPEND
  127. PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)
  128. set(pybind11_INCLUDE_DIRS
  129. "${pybind11_INCLUDE_DIR}" "${${_Python}_INCLUDE_DIRS}"
  130. CACHE INTERNAL "Directories where pybind11 and possibly Python headers are located")
  131. endif()
  132. if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
  133. set_property(
  134. TARGET pybind11::pybind11
  135. APPEND
  136. PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
  137. endif()
  138. # In CMake 3.18+, you can find these separately, so include an if
  139. if(TARGET ${_Python}::Python)
  140. set_property(
  141. TARGET pybind11::embed
  142. APPEND
  143. PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Python)
  144. endif()
  145. # CMake 3.15+ has this
  146. if(TARGET ${_Python}::Module)
  147. set_property(
  148. TARGET pybind11::module
  149. APPEND
  150. PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)
  151. else()
  152. set_property(
  153. TARGET pybind11::module
  154. APPEND
  155. PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)
  156. endif()
  157. # WITHOUT_SOABI and WITH_SOABI will disable the custom extension handling used by pybind11.
  158. # WITH_SOABI is passed on to python_add_library.
  159. function(pybind11_add_module target_name)
  160. cmake_parse_arguments(PARSE_ARGV 1 ARG
  161. "STATIC;SHARED;MODULE;THIN_LTO;OPT_SIZE;NO_EXTRAS;WITHOUT_SOABI" "" "")
  162. if(ARG_STATIC)
  163. set(lib_type STATIC)
  164. elseif(ARG_SHARED)
  165. set(lib_type SHARED)
  166. else()
  167. set(lib_type MODULE)
  168. endif()
  169. if("${_Python}" STREQUAL "Python")
  170. python_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
  171. elseif("${_Python}" STREQUAL "Python3")
  172. python3_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
  173. elseif("${_Python}" STREQUAL "Python2")
  174. python2_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
  175. else()
  176. message(FATAL_ERROR "Cannot detect FindPython version: ${_Python}")
  177. endif()
  178. target_link_libraries(${target_name} PRIVATE pybind11::headers)
  179. if(lib_type STREQUAL "MODULE")
  180. target_link_libraries(${target_name} PRIVATE pybind11::module)
  181. else()
  182. target_link_libraries(${target_name} PRIVATE pybind11::embed)
  183. endif()
  184. if(MSVC)
  185. target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
  186. endif()
  187. if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
  188. target_link_libraries(${target_name} PRIVATE pybind11::python2_no_register)
  189. endif()
  190. # -fvisibility=hidden is required to allow multiple modules compiled against
  191. # different pybind versions to work properly, and for some features (e.g.
  192. # py::module_local). We force it on everything inside the `pybind11`
  193. # namespace; also turning it on for a pybind module compilation here avoids
  194. # potential warnings or issues from having mixed hidden/non-hidden types.
  195. if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)
  196. set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
  197. endif()
  198. if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)
  199. set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
  200. endif()
  201. # If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions
  202. if(NOT ARG_WITHOUT_SOABI AND NOT "WITH_SOABI" IN_LIST ARG_UNPARSED_ARGUMENTS)
  203. pybind11_extension(${target_name})
  204. endif()
  205. if(ARG_NO_EXTRAS)
  206. return()
  207. endif()
  208. if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
  209. if(ARG_THIN_LTO)
  210. target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
  211. else()
  212. target_link_libraries(${target_name} PRIVATE pybind11::lto)
  213. endif()
  214. endif()
  215. if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
  216. # Strip unnecessary sections of the binary on Linux/macOS
  217. pybind11_strip(${target_name})
  218. endif()
  219. if(MSVC)
  220. target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
  221. endif()
  222. if(ARG_OPT_SIZE)
  223. target_link_libraries(${target_name} PRIVATE pybind11::opt_size)
  224. endif()
  225. endfunction()
  226. function(pybind11_extension name)
  227. # The extension is precomputed
  228. set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}")
  229. endfunction()