Strip /usr/include from apt pybind11's interface include dirs#121
Open
whitesscott wants to merge 1 commit into
Open
Strip /usr/include from apt pybind11's interface include dirs#121whitesscott wants to merge 1 commit into
whitesscott wants to merge 1 commit into
Conversation
The Debian/Ubuntu `pybind11-dev` package ships a CMake config in which
`pybind11::pybind11_headers` has
INTERFACE_INCLUDE_DIRECTORIES = ${_IMPORT_PREFIX}/include
and, for the apt install, `_IMPORT_PREFIX` resolves to `/usr`, so
`/usr/include` is propagated to every target that consumes pybind11 via
`pybind11_add_module` (in this repo, `_edgellm_runtime`).
nvcc translates that into `-isystem /usr/include` on the host g++ command
line for each CUDA source in the target. g++ then reorders its system
include chain, placing `/usr/include` before the libstdc++ header directory
`/usr/include/c++/<ver>`. libstdc++'s `<cmath>` relies on
`#include_next <math.h>` to reach the C library header; with `/usr/include`
moved to the front, nothing after `<cmath>` in the search order still
contains `math.h`, and the build fails during device_link_stub.cu.o with:
/usr/include/c++/13/cmath: fatal error: math.h: No such file or directory
#include_next <math.h>
Reproduced on Ubuntu 24.04 aarch64 (Jetson Thor) with `pybind11-dev`
2.11.1 and CUDA 13.2 + gcc 13.3. Pip-installed pybind11 is unaffected
because its `_IMPORT_PREFIX` points at the venv's site-packages, not `/usr`.
Fix: after `find_package(pybind11 CONFIG REQUIRED)`, strip `/usr/include`
from the `pybind11::pybind11_headers` target's INTERFACE_INCLUDE_DIRECTORIES.
The real pybind11 headers live in a subdirectory of `_IMPORT_PREFIX/include`
(specifically `pybind11/`) and are still exposed via the include-path
resolution rules; only the bogus root include is removed. No-op for pip
installs of pybind11.
Verified by:
- `rm -rf build && cmake ..` (no -Dpybind11_DIR override, so apt pybind11
at /usr/lib/cmake/pybind11 is picked): configure succeeds and the
generated experimental/pybind/CMakeFiles/_edgellm_runtime.dir/includes_CUDA.rsp
no longer contains a bare `-isystem /usr/include`.
- `make -j _edgellm_runtime`: device_link_stub.cu.o now compiles and the
`_edgellm_runtime.cpython-312-aarch64-linux-gnu.so` links successfully.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pybind11-devCMake config setspybind11::pybind11_headersINTERFACE_INCLUDE_DIRECTORIESto${_IMPORT_PREFIX}/include, where_IMPORT_PREFIX=/usr. That leaks/usr/includeinto every target usingpybind11_add_module— in this repo,_edgellm_runtime.-isystem /usr/includeon the host g++ command line, which reorders g++'s system include chain and puts/usr/includebefore/usr/include/c++/<ver>. libstdc++'s<cmath>then fails to satisfy#include_next <math.h>and the build dies duringdevice_link_stub.cu.o:find_package(pybind11 CONFIG REQUIRED), remove the literal/usr/includeentry frompybind11::pybind11_headers's interface include dirs. The real pybind11 headers still resolve; only the bogus root include is dropped._IMPORT_PREFIXis under the venv's site-packages, not/usr).Reproduction
pybind11-dev 2.11.1-2at/usr/lib/cmake/pybind11/.experimental/pybind/device_link_stub.cuwith the<cmath>/math.herror above.experimental/pybind/CMakeFiles/_edgellm_runtime.dir/includes_CUDA.rspno longer contains a bare-isystem /usr/include, and_edgellm_runtime.cpython-312-aarch64-linux-gnu.solinks successfully.-Dpybind11_DIR="$(python -m pybind11 --cmakedir)") continues to work with this patch — the workaround is guarded on the presence of/usr/includein the interface list.Test plan
pybind11-devon Ubuntu 24.04 aarch64 (Jetson Thor) —_edgellm_runtimetarget builds.pybind11via-Dpybind11_DIR=$(python -m pybind11 --cmakedir)— still builds, no regression.python -c "import _edgellm_runtime"succeeds against the resulting.so.pybind11::*targets is affected on x86_64.Related
<cmath>header cleanup in Use <cmath> instead of <math.h> in context attention FMHA headers #120 (which changes source files, not build system); this PR fixes a distinct build-system issue and does not depend on it.🤖 Generated with Claude Code