pybind11Tools.cmake 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. # tools/pybind11Tools.cmake -- Build system for the pybind11 modules
  2. #
  3. # Copyright (c) 2015 Wenzel Jakob <[email protected]>
  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. cmake_minimum_required(VERSION 2.8.12)
  8. # Add a CMake parameter for choosing a desired Python version
  9. if(NOT PYBIND11_PYTHON_VERSION)
  10. set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules")
  11. endif()
  12. set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4)
  13. find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
  14. include(CheckCXXCompilerFlag)
  15. include(CMakeParseArguments)
  16. if(NOT PYBIND11_CPP_STANDARD AND NOT CMAKE_CXX_STANDARD)
  17. if(NOT MSVC)
  18. check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
  19. if (HAS_CPP14_FLAG)
  20. set(PYBIND11_CPP_STANDARD -std=c++14)
  21. else()
  22. check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
  23. if (HAS_CPP11_FLAG)
  24. set(PYBIND11_CPP_STANDARD -std=c++11)
  25. else()
  26. #message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
  27. set(PYBIND11_CPP_STANDARD -std=c++11) # the check above does not work on MacOS for some reason
  28. endif()
  29. endif()
  30. elseif(MSVC)
  31. set(PYBIND11_CPP_STANDARD /std:c++14)
  32. endif()
  33. set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
  34. "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE)
  35. endif()
  36. # Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and
  37. # linkerflags are lists of flags to use. The result variable is a unique variable name for each set
  38. # of flags: the compilation result will be cached base on the result variable. If the flags work,
  39. # sets them in cxxflags_out/linkerflags_out internal cache variables (in addition to ${result}).
  40. function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out linkerflags_out)
  41. set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})
  42. check_cxx_compiler_flag("${cxxflags}" ${result})
  43. if (${result})
  44. set(${cxxflags_out} "${cxxflags}" CACHE INTERNAL "" FORCE)
  45. set(${linkerflags_out} "${linkerflags}" CACHE INTERNAL "" FORCE)
  46. endif()
  47. endfunction()
  48. # Internal: find the appropriate link time optimization flags for this compiler
  49. function(_pybind11_add_lto_flags target_name prefer_thin_lto)
  50. if (NOT DEFINED PYBIND11_LTO_CXX_FLAGS)
  51. set(PYBIND11_LTO_CXX_FLAGS "" CACHE INTERNAL "")
  52. set(PYBIND11_LTO_LINKER_FLAGS "" CACHE INTERNAL "")
  53. if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
  54. set(cxx_append "")
  55. set(linker_append "")
  56. if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
  57. # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it
  58. set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>")
  59. elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  60. set(cxx_append ";-fno-fat-lto-objects")
  61. endif()
  62. if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto)
  63. _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO_THIN
  64. "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
  65. PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
  66. endif()
  67. if (NOT HAS_FLTO_THIN)
  68. _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO
  69. "-flto${cxx_append}" "-flto${linker_append}"
  70. PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
  71. endif()
  72. elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
  73. # Intel equivalent to LTO is called IPO
  74. _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO
  75. "-ipo" "-ipo" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
  76. elseif(MSVC)
  77. # cmake only interprets libraries as linker flags when they start with a - (otherwise it
  78. # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags
  79. # with - instead of /, even if it is a bit non-standard:
  80. _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG
  81. "/GL" "-LTCG" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
  82. endif()
  83. if (PYBIND11_LTO_CXX_FLAGS)
  84. message(STATUS "LTO enabled")
  85. else()
  86. message(STATUS "LTO disabled (not supported by the compiler and/or linker)")
  87. endif()
  88. endif()
  89. # Enable LTO flags if found, except for Debug builds
  90. if (PYBIND11_LTO_CXX_FLAGS)
  91. target_compile_options(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_CXX_FLAGS}>")
  92. endif()
  93. if (PYBIND11_LTO_LINKER_FLAGS)
  94. target_link_libraries(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_LINKER_FLAGS}>")
  95. endif()
  96. endfunction()
  97. # Build a Python extension module:
  98. # pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
  99. # [NO_EXTRAS] [THIN_LTO] source1 [source2 ...])
  100. #
  101. function(pybind11_add_module target_name)
  102. set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS THIN_LTO)
  103. cmake_parse_arguments(ARG "${options}" "" "" ${ARGN})
  104. if(ARG_MODULE AND ARG_SHARED)
  105. message(FATAL_ERROR "Can't be both MODULE and SHARED")
  106. elseif(ARG_SHARED)
  107. set(lib_type SHARED)
  108. else()
  109. set(lib_type MODULE)
  110. endif()
  111. if(ARG_EXCLUDE_FROM_ALL)
  112. set(exclude_from_all EXCLUDE_FROM_ALL)
  113. endif()
  114. add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS})
  115. target_include_directories(${target_name}
  116. PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt
  117. PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config
  118. PRIVATE ${PYTHON_INCLUDE_DIRS})
  119. # Python debug libraries expose slightly different objects
  120. # https://docs.python.org/3.6/c-api/intro.html#debugging-builds
  121. # https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
  122. if(PYTHON_IS_DEBUG)
  123. target_compile_definitions(${target_name} PRIVATE Py_DEBUG)
  124. endif()
  125. # The prefix and extension are provided by FindPythonLibsNew.cmake
  126. set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
  127. set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
  128. # -fvisibility=hidden is required to allow multiple modules compiled against
  129. # different pybind versions to work properly, and for some features (e.g.
  130. # py::module_local). We force it on everything inside the `pybind11`
  131. # namespace; also turning it on for a pybind module compilation here avoids
  132. # potential warnings or issues from having mixed hidden/non-hidden types.
  133. set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
  134. if(WIN32 OR CYGWIN)
  135. # Link against the Python shared library on Windows
  136. target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES})
  137. elseif(APPLE)
  138. # It's quite common to have multiple copies of the same Python version
  139. # installed on one's system. E.g.: one copy from the OS and another copy
  140. # that's statically linked into an application like Blender or Maya.
  141. # If we link our plugin library against the OS Python here and import it
  142. # into Blender or Maya later on, this will cause segfaults when multiple
  143. # conflicting Python instances are active at the same time (even when they
  144. # are of the same version).
  145. # Windows is not affected by this issue since it handles DLL imports
  146. # differently. The solution for Linux and Mac OS is simple: we just don't
  147. # link against the Python library. The resulting shared library will have
  148. # missing symbols, but that's perfectly fine -- they will be resolved at
  149. # import time.
  150. target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup")
  151. if(ARG_SHARED)
  152. # Suppress CMake >= 3.0 warning for shared libraries
  153. set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON)
  154. endif()
  155. endif()
  156. # Make sure C++11/14 are enabled
  157. target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD})
  158. if(ARG_NO_EXTRAS)
  159. return()
  160. endif()
  161. _pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO})
  162. # NO STRIP
  163. #if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug)
  164. # # Strip unnecessary sections of the binary on Linux/Mac OS
  165. # if(CMAKE_STRIP)
  166. # if(APPLE)
  167. # add_custom_command(TARGET ${target_name} POST_BUILD
  168. # COMMAND ${CMAKE_STRIP} -x $<TARGET_FILE:${target_name}>)
  169. # else()
  170. # add_custom_command(TARGET ${target_name} POST_BUILD
  171. # COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>)
  172. # endif()
  173. # endif()
  174. #endif()
  175. if(MSVC)
  176. # /MP enables multithreaded builds (relevant when there are many files), /bigobj is
  177. # needed for bigger binding projects due to the limit to 64k addressable sections
  178. target_compile_options(${target_name} PRIVATE /MP /bigobj)
  179. endif()
  180. endfunction()