Build a C++11+ Extension module with pybind11. This automatically adds the recommended flags when you init the extension and assumes C++ sources - you can further modify the options yourself. The customizations are: * ``/EHsc`` and ``/bigobj`` on Windows * ``stdlib=libc++`
| 87 | |
| 88 | |
| 89 | class Pybind11Extension(_Extension): |
| 90 | """ |
| 91 | Build a C++11+ Extension module with pybind11. This automatically adds the |
| 92 | recommended flags when you init the extension and assumes C++ sources - you |
| 93 | can further modify the options yourself. |
| 94 | |
| 95 | The customizations are: |
| 96 | |
| 97 | * ``/EHsc`` and ``/bigobj`` on Windows |
| 98 | * ``stdlib=libc++`` on macOS |
| 99 | * ``visibility=hidden`` and ``-g0`` on Unix |
| 100 | |
| 101 | Finally, you can set ``cxx_std`` via constructor or afterwards to enable |
| 102 | flags for C++ std, and a few extra helper flags related to the C++ standard |
| 103 | level. It is _highly_ recommended you either set this, or use the provided |
| 104 | ``build_ext``, which will search for the highest supported extension for |
| 105 | you if the ``cxx_std`` property is not set. Do not set the ``cxx_std`` |
| 106 | property more than once, as flags are added when you set it. Set the |
| 107 | property to None to disable the addition of C++ standard flags. |
| 108 | |
| 109 | If you want to add pybind11 headers manually, for example for an exact |
| 110 | git checkout, then set ``include_pybind11=False``. |
| 111 | """ |
| 112 | |
| 113 | # flags are prepended, so that they can be further overridden, e.g. by |
| 114 | # ``extra_compile_args=["-g"]``. |
| 115 | |
| 116 | def _add_cflags(self, flags: list[str]) -> None: |
| 117 | self.extra_compile_args[:0] = flags |
| 118 | |
| 119 | def _add_ldflags(self, flags: list[str]) -> None: |
| 120 | self.extra_link_args[:0] = flags |
| 121 | |
| 122 | def __init__(self, *args: Any, **kwargs: Any) -> None: |
| 123 | self._cxx_level = 0 |
| 124 | cxx_std = kwargs.pop("cxx_std", 0) |
| 125 | |
| 126 | if "language" not in kwargs: |
| 127 | kwargs["language"] = "c++" |
| 128 | |
| 129 | include_pybind11 = kwargs.pop("include_pybind11", True) |
| 130 | |
| 131 | super().__init__(*args, **kwargs) |
| 132 | |
| 133 | # Include the installed package pybind11 headers |
| 134 | if include_pybind11: |
| 135 | # If using setup_requires, this fails the first time - that's okay |
| 136 | try: |
| 137 | import pybind11 |
| 138 | |
| 139 | pyinc = pybind11.get_include() |
| 140 | |
| 141 | if pyinc not in self.include_dirs: |
| 142 | self.include_dirs.append(pyinc) |
| 143 | except ModuleNotFoundError: |
| 144 | pass |
| 145 | |
| 146 | self.cxx_std = cxx_std |