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