blob: 2e7a9310f10b718e7a518704602535b35fb4742f [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
73# Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter
74execute_process(COMMAND ${_Python}::Python -c "import sys; print(hasattr(sys, 'gettotalrefcount'))"
75 OUTPUT_VARIABLE PYTHON_IS_DEBUG)
76
77# Python debug libraries expose slightly different objects before 3.8
78# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
79# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
80if(PYTHON_IS_DEBUG)
81 set_property(
82 TARGET pybind::pybind11
83 APPEND
84 PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
85endif()
86
87# Check on every access - since Python2 and Python3 could have been used - do nothing in that case.
88
89if(DEFINED ${_Python}_INCLUDE_DIRS)
90 set_property(
91 TARGET pybind11::pybind11
92 APPEND
93 PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>)
94endif()
95
96if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
97 set_property(
98 TARGET pybind11::pybind11
99 APPEND
100 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
101endif()
102
103# In CMake 3.18+, you can find these separately, so include an if
104if(TARGET ${_Python}::${_Python})
105 set_property(
106 TARGET pybind11::embed
107 APPEND
108 PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::${_Python})
109endif()
110
111# CMake 3.15+ has this
112if(TARGET ${_Python}::Module)
113 set_property(
114 TARGET pybind11::module
115 APPEND
116 PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)
117else()
118 set_property(
119 TARGET pybind11::module
120 APPEND
121 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)
122endif()
123
124function(pybind11_add_module target_name)
125 cmake_parse_arguments(PARSE_ARGV 1 ARG "STATIC;SHARED;MODULE;THIN_LTO;NO_EXTRAS" "" "")
126
127 if(ARG_ADD_LIBRARY_STATIC)
128 set(type STATIC)
129 elseif(ARG_ADD_LIBRARY_SHARED)
130 set(type SHARED)
131 else()
132 set(type MODULE)
133 endif()
134
135 if("${_Python}" STREQUAL "Python")
136 python_add_library(${target_name} ${type} WITH_SOABI ${ARG_UNPARSED_ARGUMENTS})
137 elseif("${_Python}" STREQUAL "Python3")
138 python3_add_library(${target_name} ${type} WITH_SOABI ${ARG_UNPARSED_ARGUMENTS})
139 elseif("${_Python}" STREQUAL "Python2")
140 python2_add_library(${target_name} ${type} WITH_SOABI ${ARG_UNPARSED_ARGUMENTS})
141 else()
142 message(FATAL_ERROR "Cannot detect FindPython version: ${_Python}")
143 endif()
144
145 target_link_libraries(${target_name} PRIVATE pybind11::headers)
146
147 if(type STREQUAL "MODULE")
148 target_link_libraries(${target_name} PRIVATE pybind11::module)
149 else()
150 target_link_libraries(${target_name} PRIVATE pybind11::embed)
151 endif()
152
153 if(MSVC)
154 target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
155 endif()
156
157 if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
158 target_link_libraries(${target_name} PRIVATE pybind11::python2_no_register)
159 endif()
160
161 set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden"
162 CUDA_VISIBILITY_PRESET "hidden")
163
164 if(ARG_NO_EXTRAS)
165 return()
166 endif()
167
168 if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
169 if(ARG_THIN_LTO)
170 target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
171 else()
172 target_link_libraries(${target_name} PRIVATE pybind11::lto)
173 endif()
174 endif()
175
176 if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
177 # Strip unnecessary sections of the binary on Linux/Mac OS
178 pybind11_strip(${target_name})
179 endif()
180
181 if(MSVC)
182 target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
183 endif()
184endfunction()
185
186function(pybind11_extension name)
187 set_property(TARGET ${name} PROPERTY PREFIX "")
188
189 if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
190 set_property(TARGET ${name} PROPERTY SUFFIX ".pyd")
191 endif()
192
193 if(${_Python}_SOABI)
194 get_property(
195 suffix
196 TARGET ${name}
197 PROPERTY SUFFIX)
198 if(NOT suffix)
199 set(suffix "${CMAKE_SHARED_MODULE_SUFFIX}")
200 endif()
201 set_property(TARGET ${name} PROPERTY SUFFIX ".${${_Python}_SOABI}${suffix}")
202 endif()
203endfunction()