4 This module provides helpers for C++11+ projects using pybind11. 8 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved. 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions are met: 13 1. Redistributions of source code must retain the above copyright notice, this 14 list of conditions and the following disclaimer. 16 2. Redistributions in binary form must reproduce the above copyright notice, 17 this list of conditions and the following disclaimer in the documentation 18 and/or other materials provided with the distribution. 20 3. Neither the name of the copyright holder nor the names of its contributors 21 may be used to endorse or promote products derived from this software 22 without specific prior written permission. 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 from setuptools.command.build_ext
import build_ext
as _build_ext
46 from setuptools
import Extension
as _Extension
48 from distutils.command.build_ext
import build_ext
as _build_ext
49 from distutils.extension
import Extension
as _Extension
51 import distutils.errors
54 WIN = sys.platform.startswith(
"win32")
55 PY2 = sys.version_info[0] < 3
56 MACOS = sys.platform.startswith(
"darwin")
57 STD_TMPL =
"/std:c++{}" if WIN
else "-std=c++{}" 69 Build a C++11+ Extension module with pybind11. This automatically adds the 70 recommended flags when you init the extension and assumes C++ sources - you 71 can further modify the options yourself. 73 The customizations are: 75 * ``/EHsc`` and ``/bigobj`` on Windows 76 * ``stdlib=libc++`` on macOS 77 * ``visibility=hidden`` and ``-g0`` on Unix 79 Finally, you can set ``cxx_std`` via constructor or afterwords to enable 80 flags for C++ std, and a few extra helper flags related to the C++ standard 81 level. It is _highly_ recommended you either set this, or use the provided 82 ``build_ext``, which will search for the highest supported extension for 83 you if the ``cxx_std`` property is not set. Do not set the ``cxx_std`` 84 property more than once, as flags are added when you set it. Set the 85 property to None to disable the addition of C++ standard flags. 87 If you want to add pybind11 headers manually, for example for an exact 88 git checkout, then set ``include_pybind11=False``. 90 Warning: do not use property-based access to the instance on Python 2 - 91 this is an ugly old-style class due to Distutils. 96 if flag
not in self.extra_compile_args:
97 self.extra_compile_args.append(flag)
101 if flag
not in self.extra_compile_args:
102 self.extra_link_args.append(flag)
107 cxx_std = kwargs.pop(
"cxx_std", 0)
109 if "language" not in kwargs:
110 kwargs[
"language"] =
"c++" 112 include_pybind11 = kwargs.pop(
"include_pybind11",
True)
116 _Extension.__init__(self, *args, **kwargs)
124 pyinc = pybind11.get_include()
126 if pyinc
not in self.include_dirs:
127 self.include_dirs.append(pyinc)
132 Pybind11Extension.cxx_std.__set__(self, cxx_std)
145 The CXX standard level. If set, will add the required flags. If left 146 at 0, it will trigger an automatic search when pybind11's build_ext 147 is used. If None, will have no effect. Besides just the flags, this 148 may add a register warning/error fix for Python 2 or macos-min 10.9 157 warnings.warn(
"You cannot safely change the cxx_level after setting it!")
160 if WIN
and level == 11:
168 self.extra_compile_args.append(STD_TMPL.format(level))
170 if MACOS
and "MACOSX_DEPLOYMENT_TARGET" not in os.environ:
172 macosx_min =
"-mmacosx-version-min=" + (
"10.9" if level < 17
else "10.14")
173 self.extra_compile_args.append(macosx_min)
174 self.extra_link_args.append(macosx_min)
178 self.extra_compile_args.append(
"/wd503" if WIN
else "-Wno-register")
179 elif not WIN
and level >= 14:
180 self.extra_compile_args.append(
"-Wno-deprecated-register")
184 tmp_chdir_lock = threading.Lock()
185 cpp_cache_lock = threading.Lock()
188 @contextlib.contextmanager
190 "Prepare and enter a temporary directory, cleanup when done" 196 tmpdir = tempfile.mkdtemp()
201 shutil.rmtree(tmpdir)
207 Return the flag if a flag name is supported on the 208 specified compiler, otherwise None (can be used as a boolean). 209 If multiple flags are passed, return the first that matches. 213 fname =
"flagcheck.cpp" 214 with open(fname,
"w")
as f:
215 f.write(
"int main (int argc, char **argv) { return 0; }")
218 compiler.compile([fname], extra_postargs=[flag])
219 except distutils.errors.CompileError:
225 cpp_flag_cache =
None 230 Return the max supported C++ std level (17, 14, or 11). 233 global cpp_flag_cache
238 return cpp_flag_cache
240 levels = [17, 14] + ([]
if WIN
else [11])
243 if has_flag(compiler, STD_TMPL.format(level)):
245 cpp_flag_cache = level
248 msg =
"Unsupported compiler -- at least C++11 support is needed!" 249 raise RuntimeError(msg)
254 Customized build_ext that allows an auto-search for the highest supported 255 C++ level for Pybind11Extension. 260 Build extensions, injecting C++ std for Pybind11Extension if needed. 263 for ext
in self.extensions:
264 if hasattr(ext,
"_cxx_level")
and ext._cxx_level == 0:
270 _build_ext.build_extensions(self)
bool hasattr(handle obj, handle name)
def _add_cflags(self, flags)
def __init__(self, args, kwargs)
def _add_lflags(self, flags)
def build_extensions(self)
def auto_cpp_level(compiler)
def has_flag(compiler, flag)