Skip to content

Use stdlib-isystem for cxx stlib include path#420

Open
cerisier wants to merge 1 commit intomainfrom
stlib-isystem
Open

Use stdlib-isystem for cxx stlib include path#420
cerisier wants to merge 1 commit intomainfrom
stlib-isystem

Conversation

@cerisier
Copy link
Copy Markdown
Owner

@cerisier cerisier commented Mar 31, 2026

This change needs careful review due to its impact on correctness, long-term maintenance, and downstream users of the toolchain (e.g. rules_go, rules_foreign_cc).

Background

Until now, we passed C++ include paths via -isystem. This worked because Clang implicitly appends its builtin headers at the end of the search path (and we also pass them explicitly via -internal-isystem).

In CUDA mode (-x cuda), the driver injects an additional builtin include path (cuda_wrappers) before the standard C++ includes. This ordering is required because these wrappers override parts of the C++ standard library specifically for CUDA.

With -isystem, we lose control over this ordering, which breaks CUDA compilation.

The problem

We need to preserve Clang’s intended include ordering in CUDA mode:

<-isystem paths>
<clang/.../cuda_wrappers>
<-stdlib++-isystem paths>
<clang/.../include>

Options considered

1. Manually inject cuda_wrappers

This would restore the correct ordering, but requires reliably detecting CUDA mode.

That is non-trivial:

  • A cuda_compile action is being introduced, but
  • Many projects (e.g. XLA) compile .cc files with -x cuda, which bypasses extension-based detection

This is a good option but it means we can never be compliant with such codebases unless they rename their files to .cu or .cu.cc.

2. Rely on the Clang driver (-stdlib++-isystem) (chosen)

-stdlib++-isystem lets the driver handle ordering of standard library includes correctly, including CUDA-specific adjustments.

However, this introduces a constraint:

  • -stdlib++-isystem is ignored in C mode

What this PR does

  • In C++ (cpp_compile):

    • Pass all relevant include paths (stdlib++, libc, kernel) via -stdlib++-isystem
    • This ensures correct ordering relative to cuda_wrappers
  • In C (c_compile):

    • Continue using -isystem for libc and kernel
    • Since -stdlib++-isystem is ignored

Tradeoff

We are left with two imperfect options:

  1. Detect CUDA and manually inject cuda_wrappers

    • Requires reliable CUDA mode detection → works but not in all cases.
  2. Delegate ordering to the driver via -stdlib++-isystem

    • Correct behavior
    • But forces divergence between C and C++ include handling

This PR adopts option (2) as the only robust approach given current constraints.

@cerisier
Copy link
Copy Markdown
Owner Author

Also PR fails because windows mingw headers need also be passed -stdlib++-isystem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants