pybind11Common.cmake 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. #[======================================================[.rst
  2. Adds the following targets::
  3. pybind11::pybind11 - link to headers and pybind11
  4. pybind11::module - Adds module links
  5. pybind11::embed - Adds embed links
  6. pybind11::lto - Link time optimizations (manual selection)
  7. pybind11::thin_lto - Link time optimizations (manual selection)
  8. pybind11::python_link_helper - Adds link to Python libraries
  9. pybind11::python2_no_register - Avoid warning/error with Python 2 + C++14/7
  10. pybind11::windows_extras - MSVC bigobj and mp for building multithreaded
  11. pybind11::opt_size - avoid optimizations that increase code size
  12. Adds the following functions::
  13. pybind11_strip(target) - strip target after building on linux/macOS
  14. pybind11_find_import(module) - See if a module is installed.
  15. #]======================================================]
  16. # CMake 3.10 has an include_guard command, but we can't use that yet
  17. if(TARGET pybind11::lto)
  18. return()
  19. endif()
  20. # If we are in subdirectory mode, all IMPORTED targets must be GLOBAL. If we
  21. # are in CONFIG mode, they should be "normal" targets instead.
  22. # In CMake 3.11+ you can promote a target to global after you create it,
  23. # which might be simpler than this check.
  24. get_property(
  25. is_config
  26. TARGET pybind11::headers
  27. PROPERTY IMPORTED)
  28. if(NOT is_config)
  29. set(optional_global GLOBAL)
  30. endif()
  31. # If not run in Python mode, we still would like this to at least
  32. # include pybind11's include directory:
  33. set(pybind11_INCLUDE_DIRS
  34. "${pybind11_INCLUDE_DIR}"
  35. CACHE INTERNAL "Include directory for pybind11 (Python not requested)")
  36. # --------------------- Shared targets ----------------------------
  37. # Build an interface library target:
  38. add_library(pybind11::pybind11 IMPORTED INTERFACE ${optional_global})
  39. set_property(
  40. TARGET pybind11::pybind11
  41. APPEND
  42. PROPERTY INTERFACE_LINK_LIBRARIES pybind11::headers)
  43. # Build a module target:
  44. add_library(pybind11::module IMPORTED INTERFACE ${optional_global})
  45. set_property(
  46. TARGET pybind11::module
  47. APPEND
  48. PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
  49. # Build an embed library target:
  50. add_library(pybind11::embed IMPORTED INTERFACE ${optional_global})
  51. set_property(
  52. TARGET pybind11::embed
  53. APPEND
  54. PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
  55. # ----------------------- no register ----------------------
  56. # Workaround for Python 2.7 and C++17 (C++14 as a warning) incompatibility
  57. # This adds the flags -Wno-register and -Wno-deprecated-register if the compiler
  58. # is Clang 3.9+ or AppleClang and the compile language is CXX, or /wd5033 for MSVC (all languages,
  59. # since MSVC didn't recognize COMPILE_LANGUAGE until CMake 3.11+).
  60. add_library(pybind11::python2_no_register INTERFACE IMPORTED ${optional_global})
  61. set(clang_4plus
  62. "$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,3.9>>>")
  63. set(no_register "$<OR:${clang_4plus},$<CXX_COMPILER_ID:AppleClang>>")
  64. if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
  65. set(cxx_no_register "${no_register}")
  66. else()
  67. set(cxx_no_register "$<AND:$<COMPILE_LANGUAGE:CXX>,${no_register}>")
  68. endif()
  69. set(msvc "$<CXX_COMPILER_ID:MSVC>")
  70. set_property(
  71. TARGET pybind11::python2_no_register
  72. PROPERTY INTERFACE_COMPILE_OPTIONS
  73. "$<${cxx_no_register}:-Wno-register;-Wno-deprecated-register>" "$<${msvc}:/wd5033>")
  74. # --------------------------- link helper ---------------------------
  75. add_library(pybind11::python_link_helper IMPORTED INTERFACE ${optional_global})
  76. if(CMAKE_VERSION VERSION_LESS 3.13)
  77. # In CMake 3.11+, you can set INTERFACE properties via the normal methods, and
  78. # this would be simpler.
  79. set_property(
  80. TARGET pybind11::python_link_helper
  81. APPEND
  82. PROPERTY INTERFACE_LINK_LIBRARIES "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
  83. else()
  84. # link_options was added in 3.13+
  85. # This is safer, because you are ensured the deduplication pass in CMake will not consider
  86. # these separate and remove one but not the other.
  87. set_property(
  88. TARGET pybind11::python_link_helper
  89. APPEND
  90. PROPERTY INTERFACE_LINK_OPTIONS "$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>")
  91. endif()
  92. # ------------------------ Windows extras -------------------------
  93. add_library(pybind11::windows_extras IMPORTED INTERFACE ${optional_global})
  94. if(MSVC) # That's also clang-cl
  95. # /bigobj is needed for bigger binding projects due to the limit to 64k
  96. # addressable sections
  97. set_property(
  98. TARGET pybind11::windows_extras
  99. APPEND
  100. PROPERTY INTERFACE_COMPILE_OPTIONS /bigobj)
  101. # /MP enables multithreaded builds (relevant when there are many files) for MSVC
  102. if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # no Clang no Intel
  103. if(CMAKE_VERSION VERSION_LESS 3.11)
  104. set_property(
  105. TARGET pybind11::windows_extras
  106. APPEND
  107. PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:/MP>)
  108. else()
  109. # Only set these options for C++ files. This is important so that, for
  110. # instance, projects that include other types of source files like CUDA
  111. # .cu files don't get these options propagated to nvcc since that would
  112. # cause the build to fail.
  113. set_property(
  114. TARGET pybind11::windows_extras
  115. APPEND
  116. PROPERTY INTERFACE_COMPILE_OPTIONS
  117. $<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)
  118. endif()
  119. endif()
  120. endif()
  121. # ----------------------- Optimize binary size --------------------------
  122. add_library(pybind11::opt_size IMPORTED INTERFACE ${optional_global})
  123. if(MSVC)
  124. set(PYBIND11_OPT_SIZE /Os)
  125. else()
  126. set(PYBIND11_OPT_SIZE -Os)
  127. endif()
  128. set_property(
  129. TARGET pybind11::opt_size
  130. APPEND
  131. PROPERTY INTERFACE_COMPILE_OPTIONS $<$<CONFIG:Release>:${PYBIND11_OPT_SIZE}>
  132. $<$<CONFIG:MinSizeRel>:${PYBIND11_OPT_SIZE}>
  133. $<$<CONFIG:RelWithDebInfo>:${PYBIND11_OPT_SIZE}>)
  134. # ----------------------- Legacy option --------------------------
  135. # Warn or error if old variable name used
  136. if(PYBIND11_CPP_STANDARD)
  137. string(REGEX MATCH [[..$]] VAL "${PYBIND11_CPP_STANDARD}")
  138. if(CMAKE_CXX_STANDARD)
  139. if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)
  140. message(WARNING "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match "
  141. "PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, "
  142. "please remove PYBIND11_CPP_STANDARD from your cache")
  143. endif()
  144. else()
  145. set(supported_standards 11 14 17 20)
  146. if("${VAL}" IN_LIST supported_standards)
  147. message(WARNING "USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_CPP_STANDARD")
  148. set(CMAKE_CXX_STANDARD
  149. ${VAL}
  150. CACHE STRING "From PYBIND11_CPP_STANDARD")
  151. else()
  152. message(FATAL_ERROR "PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD "
  153. "(last two chars: ${VAL} not understood as a valid CXX std)")
  154. endif()
  155. endif()
  156. endif()
  157. # --------------------- Python specifics -------------------------
  158. # Check to see which Python mode we are in, new, old, or no python
  159. if(PYBIND11_NOPYTHON)
  160. set(_pybind11_nopython ON)
  161. elseif(
  162. PYBIND11_FINDPYTHON
  163. OR Python_FOUND
  164. OR Python2_FOUND
  165. OR Python3_FOUND)
  166. # New mode
  167. include("${CMAKE_CURRENT_LIST_DIR}/pybind11NewTools.cmake")
  168. else()
  169. # Classic mode
  170. include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
  171. endif()
  172. # --------------------- pybind11_find_import -------------------------------
  173. if(NOT _pybind11_nopython)
  174. # Check to see if modules are importable. Use REQUIRED to force an error if
  175. # one of the modules is not found. <package_name>_FOUND will be set if the
  176. # package was found (underscores replace dashes if present). QUIET will hide
  177. # the found message, and VERSION will require a minimum version. A successful
  178. # find will cache the result.
  179. function(pybind11_find_import PYPI_NAME)
  180. # CMake variables need underscores (PyPI doesn't care)
  181. string(REPLACE "-" "_" NORM_PYPI_NAME "${PYPI_NAME}")
  182. # Return if found previously
  183. if(${NORM_PYPI_NAME}_FOUND)
  184. return()
  185. endif()
  186. set(options "REQUIRED;QUIET")
  187. set(oneValueArgs "VERSION")
  188. cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "" ${ARGN})
  189. if(ARG_REQUIRED)
  190. set(status_level FATAL_ERROR)
  191. else()
  192. set(status_level WARNING)
  193. endif()
  194. execute_process(
  195. COMMAND
  196. ${${_Python}_EXECUTABLE} -c
  197. "from pkg_resources import get_distribution; print(get_distribution('${PYPI_NAME}').version)"
  198. RESULT_VARIABLE RESULT_PRESENT
  199. OUTPUT_VARIABLE PKG_VERSION
  200. ERROR_QUIET)
  201. string(STRIP "${PKG_VERSION}" PKG_VERSION)
  202. # If a result is present, this failed
  203. if(RESULT_PRESENT)
  204. set(${NORM_PYPI_NAME}_FOUND
  205. ${NORM_PYPI_NAME}-NOTFOUND
  206. CACHE INTERNAL "")
  207. # Always warn or error
  208. message(
  209. ${status_level}
  210. "Missing: ${PYPI_NAME} ${ARG_VERSION}\nTry: ${${_Python}_EXECUTABLE} -m pip install ${PYPI_NAME}"
  211. )
  212. else()
  213. if(ARG_VERSION AND PKG_VERSION VERSION_LESS ARG_VERSION)
  214. message(
  215. ${status_level}
  216. "Version incorrect: ${PYPI_NAME} ${PKG_VERSION} found, ${ARG_VERSION} required - try upgrading"
  217. )
  218. else()
  219. set(${NORM_PYPI_NAME}_FOUND
  220. YES
  221. CACHE INTERNAL "")
  222. set(${NORM_PYPI_NAME}_VERSION
  223. ${PKG_VERSION}
  224. CACHE INTERNAL "")
  225. endif()
  226. if(NOT ARG_QUIET)
  227. message(STATUS "Found ${PYPI_NAME} ${PKG_VERSION}")
  228. endif()
  229. endif()
  230. if(NOT ARG_VERSION OR (NOT PKG_VERSION VERSION_LESS ARG_VERSION))
  231. # We have successfully found a good version, cache to avoid calling again.
  232. endif()
  233. endfunction()
  234. endif()
  235. # --------------------- LTO -------------------------------
  236. include(CheckCXXCompilerFlag)
  237. # Checks whether the given CXX/linker flags can compile and link a cxx file.
  238. # cxxflags and linkerflags are lists of flags to use. The result variable is a
  239. # unique variable name for each set of flags: the compilation result will be
  240. # cached base on the result variable. If the flags work, sets them in
  241. # cxxflags_out/linkerflags_out internal cache variables (in addition to
  242. # ${result}).
  243. function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out
  244. linkerflags_out)
  245. set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})
  246. check_cxx_compiler_flag("${cxxflags}" ${result})
  247. if(${result})
  248. set(${cxxflags_out}
  249. "${cxxflags}"
  250. PARENT_SCOPE)
  251. set(${linkerflags_out}
  252. "${linkerflags}"
  253. PARENT_SCOPE)
  254. endif()
  255. endfunction()
  256. function(_pybind11_generate_lto target prefer_thin_lto)
  257. if(MINGW)
  258. message(STATUS "${target} disabled (problems with undefined symbols for MinGW for now)")
  259. return()
  260. endif()
  261. if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
  262. set(cxx_append "")
  263. set(linker_append "")
  264. if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
  265. # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it
  266. set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>")
  267. elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT MINGW)
  268. set(cxx_append ";-fno-fat-lto-objects")
  269. endif()
  270. if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto)
  271. _pybind11_return_if_cxx_and_linker_flags_work(
  272. HAS_FLTO_THIN "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
  273. PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
  274. endif()
  275. if(NOT HAS_FLTO_THIN)
  276. _pybind11_return_if_cxx_and_linker_flags_work(
  277. HAS_FLTO "-flto${cxx_append}" "-flto${linker_append}" PYBIND11_LTO_CXX_FLAGS
  278. PYBIND11_LTO_LINKER_FLAGS)
  279. endif()
  280. elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
  281. # Intel equivalent to LTO is called IPO
  282. _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO "-ipo" "-ipo"
  283. PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
  284. elseif(MSVC)
  285. # cmake only interprets libraries as linker flags when they start with a - (otherwise it
  286. # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags
  287. # with - instead of /, even if it is a bit non-standard:
  288. _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG "/GL" "-LTCG"
  289. PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
  290. endif()
  291. # Enable LTO flags if found, except for Debug builds
  292. if(PYBIND11_LTO_CXX_FLAGS)
  293. # CONFIG takes multiple values in CMake 3.19+, until then we have to use OR
  294. set(is_debug "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>")
  295. set(not_debug "$<NOT:${is_debug}>")
  296. set(cxx_lang "$<COMPILE_LANGUAGE:CXX>")
  297. if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
  298. set(genex "${not_debug}")
  299. else()
  300. set(genex "$<AND:${not_debug},${cxx_lang}>")
  301. endif()
  302. set_property(
  303. TARGET ${target}
  304. APPEND
  305. PROPERTY INTERFACE_COMPILE_OPTIONS "$<${genex}:${PYBIND11_LTO_CXX_FLAGS}>")
  306. if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
  307. message(STATUS "${target} enabled")
  308. endif()
  309. else()
  310. if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
  311. message(STATUS "${target} disabled (not supported by the compiler and/or linker)")
  312. endif()
  313. endif()
  314. if(PYBIND11_LTO_LINKER_FLAGS)
  315. if(CMAKE_VERSION VERSION_LESS 3.11)
  316. set_property(
  317. TARGET ${target}
  318. APPEND
  319. PROPERTY INTERFACE_LINK_LIBRARIES "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
  320. else()
  321. set_property(
  322. TARGET ${target}
  323. APPEND
  324. PROPERTY INTERFACE_LINK_OPTIONS "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
  325. endif()
  326. endif()
  327. endfunction()
  328. add_library(pybind11::lto IMPORTED INTERFACE ${optional_global})
  329. _pybind11_generate_lto(pybind11::lto FALSE)
  330. add_library(pybind11::thin_lto IMPORTED INTERFACE ${optional_global})
  331. _pybind11_generate_lto(pybind11::thin_lto TRUE)
  332. # ---------------------- pybind11_strip -----------------------------
  333. function(pybind11_strip target_name)
  334. # Strip unnecessary sections of the binary on Linux/macOS
  335. if(CMAKE_STRIP)
  336. if(APPLE)
  337. set(x_opt -x)
  338. endif()
  339. add_custom_command(
  340. TARGET ${target_name}
  341. POST_BUILD
  342. COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${target_name}>)
  343. endif()
  344. endfunction()