blob: 2af567985b6f73f16225be8c648a7c6784d36e4d [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
Wenzel Jakob3232e592020-09-30 23:49:11 +020094 ERROR_VARIABLE _PYTHON_MODULE_EXTENSION_ERR
95 OUTPUT_STRIP_TRAILING_WHITESPACE)
96
97if (_PYTHON_MODULE_EXTENSION STREQUAL "")
98 message(FATAL_ERROR "pybind11 could not query the module file extension, likely the 'distutils'"
99 "package is not installed. Full error message:\n${_PYTHON_MODULE_EXTENSION_ERR}")
100endif()
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400101
102# This needs to be available for the pybind11_extension function
103set(PYTHON_MODULE_EXTENSION
104 "${_PYTHON_MODULE_EXTENSION}"
105 CACHE INTERNAL "")
Henry Schreiner1729aae2020-08-19 12:26:26 -0400106
107# Python debug libraries expose slightly different objects before 3.8
108# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
109# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
110if(PYTHON_IS_DEBUG)
111 set_property(
Henry Schreiner56df3c42020-08-21 15:27:21 -0400112 TARGET pybind11::pybind11
Henry Schreiner1729aae2020-08-19 12:26:26 -0400113 APPEND
114 PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
115endif()
116
117# Check on every access - since Python2 and Python3 could have been used - do nothing in that case.
118
119if(DEFINED ${_Python}_INCLUDE_DIRS)
120 set_property(
121 TARGET pybind11::pybind11
122 APPEND
123 PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>)
124endif()
125
126if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
127 set_property(
128 TARGET pybind11::pybind11
129 APPEND
130 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
131endif()
132
133# In CMake 3.18+, you can find these separately, so include an if
134if(TARGET ${_Python}::${_Python})
135 set_property(
136 TARGET pybind11::embed
137 APPEND
138 PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::${_Python})
139endif()
140
141# CMake 3.15+ has this
142if(TARGET ${_Python}::Module)
143 set_property(
144 TARGET pybind11::module
145 APPEND
146 PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)
147else()
148 set_property(
149 TARGET pybind11::module
150 APPEND
151 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)
152endif()
153
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400154# WITHOUT_SOABI and WITH_SOABI will disable the custom extension handling used by pybind11.
155# WITH_SOABI is passed on to python_add_library.
Henry Schreiner1729aae2020-08-19 12:26:26 -0400156function(pybind11_add_module target_name)
Wenzel Jakob36c666f2020-09-04 23:31:05 +0200157 cmake_parse_arguments(PARSE_ARGV 1 ARG
158 "STATIC;SHARED;MODULE;THIN_LTO;OPT_SIZE;NO_EXTRAS;WITHOUT_SOABI" "" "")
Henry Schreiner1729aae2020-08-19 12:26:26 -0400159
160 if(ARG_ADD_LIBRARY_STATIC)
161 set(type STATIC)
162 elseif(ARG_ADD_LIBRARY_SHARED)
163 set(type SHARED)
164 else()
165 set(type MODULE)
166 endif()
167
168 if("${_Python}" STREQUAL "Python")
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400169 python_add_library(${target_name} ${type} ${ARG_UNPARSED_ARGUMENTS})
Henry Schreiner1729aae2020-08-19 12:26:26 -0400170 elseif("${_Python}" STREQUAL "Python3")
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400171 python3_add_library(${target_name} ${type} ${ARG_UNPARSED_ARGUMENTS})
Henry Schreiner1729aae2020-08-19 12:26:26 -0400172 elseif("${_Python}" STREQUAL "Python2")
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400173 python2_add_library(${target_name} ${type} ${ARG_UNPARSED_ARGUMENTS})
Henry Schreiner1729aae2020-08-19 12:26:26 -0400174 else()
175 message(FATAL_ERROR "Cannot detect FindPython version: ${_Python}")
176 endif()
177
178 target_link_libraries(${target_name} PRIVATE pybind11::headers)
179
180 if(type STREQUAL "MODULE")
181 target_link_libraries(${target_name} PRIVATE pybind11::module)
182 else()
183 target_link_libraries(${target_name} PRIVATE pybind11::embed)
184 endif()
185
186 if(MSVC)
187 target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
188 endif()
189
190 if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
191 target_link_libraries(${target_name} PRIVATE pybind11::python2_no_register)
192 endif()
193
194 set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden"
195 CUDA_VISIBILITY_PRESET "hidden")
196
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400197 # If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions
198 if("${type}" STREQUAL "MODULE" AND (NOT ARG_WITHOUT_SOABI OR NOT "WITH_SOABI" IN_LIST
199 ARG_UNPARSED_ARGUMENTS))
200 pybind11_extension(${target_name})
201 endif()
202
Henry Schreiner1729aae2020-08-19 12:26:26 -0400203 if(ARG_NO_EXTRAS)
204 return()
205 endif()
206
207 if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
208 if(ARG_THIN_LTO)
209 target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
210 else()
211 target_link_libraries(${target_name} PRIVATE pybind11::lto)
212 endif()
213 endif()
214
215 if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
Henry Schreinerfd61f502020-09-16 17:13:41 -0400216 # Strip unnecessary sections of the binary on Linux/macOS
Henry Schreiner1729aae2020-08-19 12:26:26 -0400217 pybind11_strip(${target_name})
218 endif()
219
220 if(MSVC)
221 target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
222 endif()
Wenzel Jakob36c666f2020-09-04 23:31:05 +0200223
224 if(ARG_OPT_SIZE)
225 target_link_libraries(${target_name} PRIVATE pybind11::opt_size)
226 endif()
Henry Schreiner1729aae2020-08-19 12:26:26 -0400227endfunction()
228
229function(pybind11_extension name)
Henry Schreinerce1a07e2020-09-04 21:54:09 -0400230 # The extension is precomputed
231 set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}")
Henry Schreiner1729aae2020-08-19 12:26:26 -0400232
Henry Schreiner1729aae2020-08-19 12:26:26 -0400233endfunction()