Parsing of /showIncludes MSVC compiler output is incorrect when INCLUDES contains relative paths.
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 72
Description
### Description of the problem / feature request:
On Windows Bazel uses `/showIncludes` compiler option to get the list of headers used during compilation and generate possible "undeclared header usage" errors. Unfortunately it seems the code parsing compiler output expects the paths to always be absolute. In reality MSVC follows what it is told in INCLUDES - if the path there is absolute, then the path in compiler output would be absolute, but if the path in INCLUDES is relative, then in compiler output it is also relative, which is logical.
Using absolute paths in INCLUDES effectively blocks hermeticity.
The problem is not apparent because by default Bazel discovers local MSVC installation and uses that. Of course, all standard MSVC installations only have absolute paths used in INCLUDES. Which is Ok as nobody expects discovered toolchain to be hermetic. But if we want to use our own fully hermetic MSVC toolchain we must use relative paths everywhere and in INCLUDES which causes Bazel to wrongfully complain about undeclared inclusions. Bummer.
### Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
It would take me substantial effort to produce a standalone repro, so I would like to know if it is needed before I spend that time. In short it is Windows build with some system include folders specified in INCLUDES env.var. as relative (to execroot) paths.
### What operating system are you running Bazel on?
This problem is specific for Windows and MSVC.
### What's the output of `bazel info release`?
4.2.1
### Have you found anything relevant by searching the web?
I found the code which does the parsing [here](https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/cpp/ShowIncludesFilter.java;l=170?q=showIncludes&ss=bazel%2Fbazel). @meteorcloudy your name is all over it, so you must have a good idea about it.
I even have trouble understanding the following comment from that code:
```
// Prefix the matched header path with "..\". This way, external repo header paths are
// resolved to "\..\\", and main repo file paths are
// resolved to "\..\\", which is nicely normalized to
// "\".
```
If two dots are inserted AFTER repo name I would understand it, but inserting it BEFORE repo name does not make sense to me. Could you please clarify?
Contributor guide
Research direction
Start with src/main/java/com/google/devtools/build/lib/rules/cpp/ShowIncludesFilter.java, especially the parsing around line 170 and its path-normalization comment. Reproduce a Windows MSVC build with relative paths in INCLUDES, then verify that relative headers are parsed correctly without wrongful undeclared-header errors; a standalone repro may be needed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, java
- Domain
- build-system, compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100