blob: 8710cff58c48628e20c05330f6a01e8f3879cff0 [file] [log] [blame]
Henry Schreiner1729aae2020-08-19 12:26:26 -04001# 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
8get_property(
9 is_config
10 TARGET pybind11::headers
11 PROPERTY IMPORTED)
12
13if(pybind11_FIND_QUIETLY)
14 set(_pybind11_quiet QUIET)
15endif()
16
17if(CMAKE_VERSION VERSION_LESS 3.12)
18 message(FATAL_ERROR "You cannot use the new FindPython module with CMake < 3.12")
19endif()
20
21if(NOT Python_FOUND
22 AND NOT Python3_FOUND
23 AND NOT Python2_FOUND)
24 if(NOT DEFINED Python_FIND_IMPLEMENTATIONS)
25 set(Python_FIND_IMPLEMENTATIONS CPython PyPy)
26 endif()
27
28 # GitHub Actions like activation
29 if(NOT DEFINED Python_ROOT_DIR AND DEFINED ENV{pythonLocation})
30 set(Python_ROOT_DIR "$ENV{pythonLocation}")
31 endif()
32
33 find_package(Python REQUIRED COMPONENTS Interpreter Development ${_pybind11_quiet})
34
35 # If we are in submodule mode, export the Python targets to global targets.
36 # If this behavior is not desired, FindPython _before_ pybind11.
37 if(NOT is_config)
38 set_property(TARGET Python::Python PROPERTY IMPORTED_GLOBAL TRUE)
39 set_property(TARGET Python::Interpreter PROPERTY IMPORTED_GLOBAL TRUE)
40 if(TARGET Python::Module)
41 set_property(TARGET Python::Module PROPERTY IMPORTED_GLOBAL TRUE)
42 endif()
43 endif()
44endif()
45
46if(Python_FOUND)
47 set(_Python
48 Python
49 CACHE INTERNAL "" FORCE)
50elseif(Python3_FOUND AND NOT Python2_FOUND)
51 set(_Python
52 Python3
53 CACHE INTERNAL "" FORCE)
54elseif(Python2_FOUND AND NOT Python3_FOUND)
55 set(_Python
56 Python2
57 CACHE INTERNAL "" FORCE)
58else()
59 message(AUTHOR_WARNING "Python2 and Python3 both present, pybind11 in "
60 "PYBIND11_NOPYTHON mode (manually activate to silence warning)")
61 set(_pybind11_nopython ON)
62 return()
63endif()
64
65if(PYBIND11_MASTER_PROJECT)
66 if(${_Python}_INTERPRETER_ID MATCHES "PyPy")
67 message(STATUS "PyPy ${${_Python}_PyPy_VERSION} (Py ${${_Python}_VERSION})")
68 else()
69 message(STATUS "${_Python} ${${_Python}_VERSION}")
70 endif()
71endif()
72
Henry Schreinere01f4922020-09-21 18:34:48 -040073# If a user finds Python, they may forget to include the Interpreter component
74# and the following two steps require it. It is highly recommended by CMake
75# when finding development libraries anyway, so we will require it.
76if(NOT DEFINED ${_Python}_EXECUTABLE)
77 message(
78 FATAL_ERROR
79 "${_Python} was found without the Interpreter component. Pybind11 requires this component.")
80
81endif()
82
Henry Schreiner1729aae2020-08-19 12:26:26 -040083# Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter
Henry Schreinerce1a07e2020-09-04 21:54:09 -040084execute_process(
85 COMMAND "${${_Python}_EXECUTABLE}" "-c" "import sys; sys.exit(hasattr(sys, 'gettotalrefcount'))"
86 RESULT_VARIABLE PYTHON_IS_DEBUG)
87
88# Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is
89# required for PyPy3 (as of 7.3.1)
90execute_process(
91 COMMAND "${${_Python}_EXECUTABLE}" "-c"
92 "from distutils import sysconfig; print(sysconfig.get_config_var('SO'))"
93 OUTPUT_VARIABLE _PYTHON_MODULE_EXTENSION
94 ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
95
96# This needs to be available for the pybind11_extension function
97set(PYTHON_MODULE_EXTENSION
98 "${_PYTHON_MODULE_EXTENSION}"
99 CACHE INTERNAL "")
Henry Schreiner1729aae2020-08-19 12:26:26 -0400100
101# Python debug libraries expose slightly different objects before 3.8
102# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
103# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
104if(PYTHON_IS_DEBUG)
105 set_property(
Henry Schreiner56df3c42020-08-21 15:27:21 -0400106 TARGET pybind11::pybind11
Henry Schreiner1729aae2020-08-19 12:26:26 -0400107 APPEND
108 PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
109endif()
110
111# Check on every access - since Python2 and Python3 could have been used - do nothing in that case.
112
113if(DEFINED ${_Python}_INCLUDE_DIRS)
114 set_property(
115 TARGET pybind11::pybind11
116 APPEND
117 PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>)
118endif()
119
120if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
121 set_property(
122 TARGET pybind11::pybind11
123 APPEND
124 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
125endif()
126
127# In CMake 3.18+, you can find these separately, so include an if
128if(TARGET ${_Python}::${_Python})
129 set_property(
130 TARGET pybind11::embed
131 APPEND
132 PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::${_Python})
133endif()
134
135# CMake 3.15+ has this
136if(TARGET ${_Python}::Module)
137 set_property(
138 TARGET pybind11::module
139 APPEND
140 PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)
141else()
142 set_property(
143 TARGET pybind11::module
144 APPEND
145 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)
146endif()
147
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400148# WITHOUT_SOABI and WITH_SOABI will disable the custom extension handling used by pybind11.
149# WITH_SOABI is passed on to python_add_library.
Henry Schreiner1729aae2020-08-19 12:26:26 -0400150function(pybind11_add_module target_name)
Wenzel Jakob36c666f2020-09-04 23:31:05 +0200151 cmake_parse_arguments(PARSE_ARGV 1 ARG
152 "STATIC;SHARED;MODULE;THIN_LTO;OPT_SIZE;NO_EXTRAS;WITHOUT_SOABI" "" "")
Henry Schreiner1729aae2020-08-19 12:26:26 -0400153
154 if(ARG_ADD_LIBRARY_STATIC)
155 set(type STATIC)
156 elseif(ARG_ADD_LIBRARY_SHARED)
157 set(type SHARED)
158 else()
159 set(type MODULE)
160 endif()
161
162 if("${_Python}" STREQUAL "Python")
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400163 python_add_library(${target_name} ${type} ${ARG_UNPARSED_ARGUMENTS})
Henry Schreiner1729aae2020-08-19 12:26:26 -0400164 elseif("${_Python}" STREQUAL "Python3")
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400165 python3_add_library(${target_name} ${type} ${ARG_UNPARSED_ARGUMENTS})
Henry Schreiner1729aae2020-08-19 12:26:26 -0400166 elseif("${_Python}" STREQUAL "Python2")
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400167 python2_add_library(${target_name} ${type} ${ARG_UNPARSED_ARGUMENTS})
Henry Schreiner1729aae2020-08-19 12:26:26 -0400168 else()
169 message(FATAL_ERROR "Cannot detect FindPython version: ${_Python}")
170 endif()
171
172 target_link_libraries(${target_name} PRIVATE pybind11::headers)
173
174 if(type STREQUAL "MODULE")
175 target_link_libraries(${target_name} PRIVATE pybind11::module)
176 else()
177 target_link_libraries(${target_name} PRIVATE pybind11::embed)
178 endif()
179
180 if(MSVC)
181 target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
182 endif()
183
184 if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
185 target_link_libraries(${target_name} PRIVATE pybind11::python2_no_register)
186 endif()
187
188 set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden"
189 CUDA_VISIBILITY_PRESET "hidden")
190
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400191 # If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions
192 if("${type}" STREQUAL "MODULE" AND (NOT ARG_WITHOUT_SOABI OR NOT "WITH_SOABI" IN_LIST
193 ARG_UNPARSED_ARGUMENTS))
194 pybind11_extension(${target_name})
195 endif()
196
Henry Schreiner1729aae2020-08-19 12:26:26 -0400197 if(ARG_NO_EXTRAS)
198 return()
199 endif()
200
201 if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
202 if(ARG_THIN_LTO)
203 target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
204 else()
205 target_link_libraries(${target_name} PRIVATE pybind11::lto)
206 endif()
207 endif()
208
209 if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
Henry Schreinerfd61f502020-09-16 17:13:41 -0400210 # Strip unnecessary sections of the binary on Linux/macOS
Henry Schreiner1729aae2020-08-19 12:26:26 -0400211 pybind11_strip(${target_name})
212 endif()
213
214 if(MSVC)
215 target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
216 endif()
Wenzel Jakob36c666f2020-09-04 23:31:05 +0200217
218 if(ARG_OPT_SIZE)
219 target_link_libraries(${target_name} PRIVATE pybind11::opt_size)
220 endif()
Henry Schreiner1729aae2020-08-19 12:26:26 -0400221endfunction()
222
223function(pybind11_extension name)
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400224 # The extension is precomputed
225 set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}")
Henry Schreiner1729aae2020-08-19 12:26:26 -0400226
Henry Schreiner1729aae2020-08-19 12:26:26 -0400227endfunction()