aspect-build / aspect-build/rules_lint
clang_tidy aspect strips absolute -isystem paths as MSVC flags → 'cstdint' file not found with hermetic LLVM toolchain on macOS
- Dominant language
- Starlark
- Stars
- 154
- Forks
- 125
- Avg merge
- 3d 21h
- Merged PRs (30d)
- 20
Description
> **Disclosure:** This report was generated by Claude (Anthropic) from an automated investigation while integrating the `clang_tidy` aspect with a hermetic LLVM toolchain. The root cause was traced to source and the repro observed directly, but please verify before acting.
### Summary
On macOS with a hermetic LLVM toolchain (`toolchains_llvm`), the `clang_tidy` aspect fails every C++ target with:
```
error: 'cstdint' file not found [clang-diagnostic-error]
```
The cause is `_update_flag` in `lint/clang_tidy.bzl` treating any argument that starts with `/` as an MSVC `/flag` and dropping it — which includes the **absolute C++ standard-library include path** that the toolchain passes as a separate token after `-isystem`.
### Root cause
`lint/clang_tidy.bzl` (v2.7.1, also present on `main`), in `_update_flag`:
```python
elif (flag.startswith("/")):
# strip all other microsoft params
return []
```
`_safe_flags` runs `_update_flag` over each token of the toolchain compile command line individually. Bazel / `toolchains_llvm` passes system include dirs as **two tokens**, e.g.:
```
-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1
```
The path token starts with `/`, so it is stripped (the preceding `-isystem` is kept, now orphaned). The libc++ headers become unreachable, so `` (and other stdlib headers) fail to resolve.
This is macOS-specific in practice: on Linux the toolchain's libc++/sysroot paths are exec-root-relative (`external/...`), so they don't start with `/` and survive. On macOS, `toolchains_llvm` uses the absolute Xcode SDK path.
### Reproduction
- Bazel 9.x (Bzlmod), macOS.
- Hermetic toolchain via `toolchains_llvm` (e.g. LLVM 19.x).
- A trivial `cc_library` whose source does `#include `.
- Run the `clang_tidy` aspect over it.
Result: `error: 'cstdint' file not found [clang-diagnostic-error]`.
Setting `verbose = True` on the aspect confirms it — the absolute libc++ path appears in the `skipped flags:` line:
```
skipped flags: -Wall -Wthread-safety -Wself-assign /Applications/Xcode.app/.../MacOSX.sdk/usr/include/c++/v1 -Wno-module-import-in-extern-c -Wno-builtin-macro-redefined
```
### Impact
The `clang_tidy` aspect is effectively unusable with a hermetic LLVM toolchain on macOS — every C++ translation unit errors out on standard-library headers. It is independent of which checks are enabled, since the failure is a `clang-diagnostic-error` at parse time.
### Suggested fix
The MSVC `/flag` heuristic should not consume absolute POSIX paths. Options:
- Don't strip a `/`-prefixed token that is the **argument of a preceding** `-isystem`/`-I`/`-iquote`/`-isysroot` (handle include-flag pairs together).
- Only apply the MSVC remap when actually targeting MSVC (gate on the toolchain/platform).
- Distinguish MSVC flags from filesystem paths (an absolute path with `/` separators that exists on disk is not `/D`, `/I`, or `/std:`).
### Related
- #566 — same failure family (clang-tidy can't resolve toolchain stdlib headers on macOS), reported as a symptom; the underlying `_update_flag` strip isn't identified there.
- #779 (open) — adds `-isysroot`; helps the symptom, but the `/`-prefix strip in `_update_flag` remains, so absolute `-isystem` paths are still dropped.
### Versions
- `aspect_rules_lint` v2.7.1 (strip also present on `main`)
- Bazel 9.1.x, `toolchains_llvm` (LLVM 19.1.7), macOS
Contributor guide
Research direction
Read `_update_flag` and `_safe_flags` in `lint/clang_tidy.bzl`, then reproduce with the described `cc_library` including `` and the `clang_tidy` aspect on macOS using `toolchains_llvm`. Check how the separate `-isystem` path token is handled. Done means the absolute SDK include path is preserved and the aspect no longer reports `cstdint` missing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100