blob: f05845179fd84f6942ff334bb0e3c2f1794886e7 [file] [log] [blame]
Henry Schreiner1729aae2020-08-19 12:26:26 -04001#[======================================================[.rst
2
3Adds the following targets::
4
5 pybind11::pybind11 - link to headers and pybind11
6 pybind11::module - Adds module links
7 pybind11::embed - Adds embed links
8 pybind11::lto - Link time optimizations (manual selection)
9 pybind11::thin_lto - Link time optimizations (manual selection)
10 pybind11::python_link_helper - Adds link to Python libraries
11 pybind11::python2_no_register - Avoid warning/error with Python 2 + C++14/7
12 pybind11::windows_extras - MSVC bigobj and mp for building multithreaded
13
14Adds the following functions::
15
16 pybind11_strip(target) - strip target after building on linux/macOS
17
18
19#]======================================================]
20
21# CMake 3.10 has an include_guard command, but we can't use that yet
22if(TARGET pybind11::lto)
23 return()
24endif()
25
26# If we are in subdirectory mode, all IMPORTED targets must be GLOBAL. If we
27# are in CONFIG mode, they should be "normal" targets instead.
28# In CMake 3.11+ you can promote a target to global after you create it,
29# which might be simpler than this check.
30get_property(
31 is_config
32 TARGET pybind11::headers
33 PROPERTY IMPORTED)
34if(NOT is_config)
35 set(optional_global GLOBAL)
36endif()
37
38# --------------------- Shared targets ----------------------------
39
40# Build an interface library target:
41add_library(pybind11::pybind11 IMPORTED INTERFACE ${optional_global})
42set_property(
43 TARGET pybind11::pybind11
44 APPEND
45 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::headers)
46
47# Build a module target:
48add_library(pybind11::module IMPORTED INTERFACE ${optional_global})
49set_property(
50 TARGET pybind11::module
51 APPEND
52 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
53
54# Build an embed library target:
55add_library(pybind11::embed IMPORTED INTERFACE ${optional_global})
56set_property(
57 TARGET pybind11::embed
58 APPEND
59 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
60
61# ----------------------- no register ----------------------
62
63# Workaround for Python 2.7 and C++17 (C++14 as a warning) incompatibility
64# This adds the flags -Wno-register and -Wno-deprecated-register if the compiler
65# is Clang 3.9+ or AppleClang and the compile language is CXX, or /wd5033 for MSVC (all languages,
66# since MSVC didn't recognize COMPILE_LANGUAGE until CMake 3.11+).
67
68add_library(pybind11::python2_no_register INTERFACE IMPORTED ${optional_global})
69set(clang_4plus
70 "$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,3.9>>>")
71set(no_register "$<OR:${clang_4plus},$<CXX_COMPILER_ID:AppleClang>>")
72
73if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
74 set(cxx_no_register "${no_register}")
75else()
76 set(cxx_no_register "$<AND:$<COMPILE_LANGUAGE:CXX>,${no_register}>")
77endif()
78
79set(msvc "$<CXX_COMPILER_ID:MSVC>")
80
81set_property(
82 TARGET pybind11::python2_no_register
83 PROPERTY INTERFACE_COMPILE_OPTIONS
84 "$<${cxx_no_register}:-Wno-register;-Wno-deprecated-register>" "$<${msvc}:/wd5033>")
85
86# --------------------------- link helper ---------------------------
87
88add_library(pybind11::python_link_helper IMPORTED INTERFACE ${optional_global})
89
90if(CMAKE_VERSION VERSION_LESS 3.13)
91 # In CMake 3.11+, you can set INTERFACE properties via the normal methods, and
92 # this would be simpler.
93 set_property(
94 TARGET pybind11::python_link_helper
95 APPEND
96 PROPERTY INTERFACE_LINK_LIBRARIES "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
97else()
98 # link_options was added in 3.13+
99 # This is safer, because you are ensured the deduplication pass in CMake will not consider
100 # these separate and remove one but not the other.
101 set_property(
102 TARGET pybind11::python_link_helper
103 APPEND
104 PROPERTY INTERFACE_LINK_OPTIONS "$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>")
105endif()
106
107# ------------------------ Windows extras -------------------------
108
109add_library(pybind11::windows_extras IMPORTED INTERFACE ${optional_global})
110
111if(MSVC)
112 # /MP enables multithreaded builds (relevant when there are many files), /bigobj is
113 # needed for bigger binding projects due to the limit to 64k addressable sections
114 set_property(
115 TARGET pybind11::windows_extras
116 APPEND
117 PROPERTY INTERFACE_COMPILE_OPTIONS /bigobj)
118
119 if(CMAKE_VERSION VERSION_LESS 3.11)
120 set_property(
121 TARGET pybind11::windows_extras
122 APPEND
123 PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:/MP>)
124 else()
125 # Only set these options for C++ files. This is important so that, for
126 # instance, projects that include other types of source files like CUDA
127 # .cu files don't get these options propagated to nvcc since that would
128 # cause the build to fail.
129 set_property(
130 TARGET pybind11::windows_extras
131 APPEND
132 PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)
133 endif()
134endif()
135
136# ----------------------- Legacy option --------------------------
137
138# Warn or error if old variable name used
139if(PYBIND11_CPP_STANDARD)
140 string(REGEX MATCH [[..$]] VAL "${PYBIND11_CPP_STANDARD}")
141 if(CMAKE_CXX_STANDARD)
142 if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)
143 message(WARNING "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match "
144 "PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, "
145 "please remove PYBIND11_CPP_STANDARD from your cache")
146 endif()
147 else()
148 set(supported_standards 11 14 17 20)
149 if("${VAL}" IN_LIST supported_standards)
150 message(WARNING "USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_PYTHON_VERSION")
151 set(CMAKE_CXX_STANDARD
152 ${VAL}
153 CACHE STRING "From PYBIND11_CPP_STANDARD")
154 else()
155 message(FATAL_ERROR "PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD "
156 "(last two chars: ${VAL} not understood as a valid CXX std)")
157 endif()
158 endif()
159endif()
160
161# --------------------- Python specifics -------------------------
162
163# Check to see which Python mode we are in, new, old, or no python
164if(PYBIND11_NOPYTHON)
165 set(_pybind11_nopython ON)
166elseif(
167 PYBIND11_FINDPYTHON
168 OR Python_FOUND
169 OR Python2_FOUND
170 OR Python3_FOUND)
171 # New mode
172 include("${CMAKE_CURRENT_LIST_DIR}/pybind11NewTools.cmake")
173
174else()
175
176 # Classic mode
177 include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
178
179endif()
180
181# --------------------- LTO -------------------------------
182
183include(CheckCXXCompilerFlag)
184
185# Checks whether the given CXX/linker flags can compile and link a cxx file.
186# cxxflags and linkerflags are lists of flags to use. The result variable is a
187# unique variable name for each set of flags: the compilation result will be
188# cached base on the result variable. If the flags work, sets them in
189# cxxflags_out/linkerflags_out internal cache variables (in addition to
190# ${result}).
191function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out
192 linkerflags_out)
193 set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})
194 check_cxx_compiler_flag("${cxxflags}" ${result})
195 if(${result})
196 set(${cxxflags_out}
197 "${cxxflags}"
198 PARENT_SCOPE)
199 set(${linkerflags_out}
200 "${linkerflags}"
201 PARENT_SCOPE)
202 endif()
203endfunction()
204
205function(_pybind11_generate_lto target prefer_thin_lto)
206 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
207 set(cxx_append "")
208 set(linker_append "")
209 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
210 # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it
211 set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>")
212 elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
213 set(cxx_append ";-fno-fat-lto-objects")
214 endif()
215
216 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto)
217 _pybind11_return_if_cxx_and_linker_flags_work(
218 HAS_FLTO_THIN "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
219 PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
220 endif()
221
222 if(NOT HAS_FLTO_THIN)
223 _pybind11_return_if_cxx_and_linker_flags_work(
224 HAS_FLTO "-flto${cxx_append}" "-flto${linker_append}" PYBIND11_LTO_CXX_FLAGS
225 PYBIND11_LTO_LINKER_FLAGS)
226 endif()
227 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
228 # Intel equivalent to LTO is called IPO
229 _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO "-ipo" "-ipo"
230 PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
231 elseif(MSVC)
232 # cmake only interprets libraries as linker flags when they start with a - (otherwise it
233 # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags
234 # with - instead of /, even if it is a bit non-standard:
235 _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG "/GL" "-LTCG"
236 PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
237 endif()
238
239 # Enable LTO flags if found, except for Debug builds
240 if(PYBIND11_LTO_CXX_FLAGS)
241 set(not_debug "$<NOT:$<CONFIG:Debug>>")
242 set(cxx_lang "$<COMPILE_LANGUAGE:CXX>")
243 if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
244 set(genex "${not_debug}")
245 else()
246 set(genex "$<AND:${not_debug},${cxx_lang}>")
247 endif()
248 set_property(
249 TARGET ${target}
250 APPEND
251 PROPERTY INTERFACE_COMPILE_OPTIONS "$<${genex}:${PYBIND11_LTO_CXX_FLAGS}>")
252 if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
253 message(STATUS "${target} enabled")
254 endif()
255 else()
256 if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
257 message(STATUS "${target} disabled (not supported by the compiler and/or linker)")
258 endif()
259 endif()
260
261 if(PYBIND11_LTO_LINKER_FLAGS)
262 if(CMAKE_VERSION VERSION_LESS 3.11)
263 set_property(
264 TARGET ${target}
265 APPEND
266 PROPERTY INTERFACE_LINK_LIBRARIES "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
267 else()
268 set_property(
269 TARGET ${target}
270 APPEND
271 PROPERTY INTERFACE_LINK_OPTIONS "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
272 endif()
273 endif()
274endfunction()
275
276add_library(pybind11::lto IMPORTED INTERFACE ${optional_global})
277_pybind11_generate_lto(pybind11::lto FALSE)
278
279add_library(pybind11::thin_lto IMPORTED INTERFACE ${optional_global})
280_pybind11_generate_lto(pybind11::thin_lto TRUE)
281
282# ---------------------- pybind11_strip -----------------------------
283
284function(pybind11_strip target_name)
285 # Strip unnecessary sections of the binary on Linux/Mac OS
286 if(CMAKE_STRIP)
287 if(APPLE)
288 set(x_opt -x)
289 endif()
290
291 add_custom_command(
292 TARGET ${target_name}
293 POST_BUILD
294 COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${target_name}>)
295 endif()
296endfunction()