-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parsing of /showIncludes MSVC compiler output is incorrect when INCLUDES contains relative paths. #13998
Comments
@konste This change was introduced at in 24c980b for I actually never noticed that INCULDES could make cl.exe output relative paths for header discovery. If that's true, we can indeed take advantage of that to make Windows toolchain more hermetic. Can you somehow construct a minimal reproduce case? /cc @andrewkatson This is an interesting Windows problem to look into. |
@meteorcloudy Thank you for the prompt response! Now that I know it is not in vain I will invest time into making the minimal standalone repro and try to debug the relevant parts of Bazel code. |
@konste Nice, thanks for looking into it! |
After many experiments I discovered that MSVC option /showIncludes indeed outputs absolute paths most of the time, BUT there is at least one exception: when INCLUDE env var contains relative paths AND debug information is not requested – it outputs relative paths! Bazel MSVC “discovery” toolchain does not encounter it because 1. Most of the time INCLUDE env var contains absolute paths and also 2. /Z7 is used always , even for fastbuild. Striving to make our MSVC toolchain hermetic we switched to relative paths in INCLUDE and our fastbuild configuration deliberately skips debug info generation (for speed), so we hit that case. I have shared pretty compact and self-contained repro here. It uses “nocopts” to remove /Z7 set by the toolchain and also adds the folder “prop_msvc_toolchain” (which is obviously relative) to “includes” attribute. |
I think it's related to this flag --strict_system_includes. By default it's turned off to allow system include paths specified with "-isystem" (instead of "-i"). But on Windows, there is no such difference, so any directory specified with "/I" is allowed. If you don't use Also on Linux and macOS, we have sandbox enabled, so this missing dependency is even caught before the header check, because the compiling action cannot even see the
|
Oh, this is not a bug. |
@konste Maybe you intended to use https://docs.bazel.build/versions/main/be/c-cpp.html#cc_library.include_prefix ? This is only available in cc_library. |
@meteorcloudy thank you, things become more clear now! Let me ask a couple of questions and then I will summarize the knowledge for anybody finding this issue in the future.
Is there any value then in running header check when sandbox is available and enabled? If no then how can it be disabled or it is disabled automatically? Regarding header folders. Those are collected from multiple sources. One is Next set of header folders comes from the I have created a tiny repro here and my experiments with it on Windows show that by default only the header from the root folder is flagged as undeclared, but when I specify Having both headers flagged matches my expectation. I am surprised it is not the default, but having the flag Is my understanding correct that I will keep experimenting on all platforms hoping to be able to enable |
I believe it is still enabled. However, I cannot think of a case where sandbox won't catch the error but header checking will. The code is here: Looks like dirs specified in
Yes, I think that's the case. |
The summary:
May be #3 is worth tracking as a separate bug? |
|
Thank you for contributing to the Bazel repository! This issue has been marked as stale since it has not had any activity in the last 1+ years. It will be closed in the next 14 days unless any other activity occurs or one of the following labels is added: "not stale", "awaiting-bazeler". Please reach out to the triage team ( |
I am seeing something similar. I have removed all absolute paths from an msvc toolchain. I could not get INCLUDES to work with a relative path, but have set:
when I compile with
But when I try with Bazel, the |
I went back and retested relative paths in INCLUDES without |
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. @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:
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?
The text was updated successfully, but these errors were encountered: