bazelbuild/bazel

C++ header validation fails for MSVC remote compile

Open

#19.733 aperta il 4 ott 2023

Vedi su GitHub
 (17 commenti) (0 reazioni) (0 assegnatari)Java (4465 fork)batch import
P3help wantedteam-Rules-CPPtype: bug

Metriche repository

Star
 (25.384 star)
Metriche merge PR
 (Merge medio 22g 20h) (77 PR mergiate in 30 g)

Descrizione

Description of the bug:

When building a cc_library that includes header files on Windows using an MSVC toolchain with remote execution, I get this error:

ERROR: C:/users/jay/code/engflow-example/cpp/BUILD:1:10: Compiling cpp/main.cc failed: undeclared inclusion(s) in rule '//cpp:cpp':
this rule is missing dependency declarations for the following files included by 'cpp/main.cc':
  'C:/_b/gjo2whp5/execroot/ws/cpp/hello.h'

Which category does this issue belong to?

C++/Objective-C Rules

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

You will need a remote execution service with Windows that can execute actions in containers. I think that makes this difficult to reproduce, though maybe Google has something internally that might work? I'm working on this at EngFlow.

Assuming you have that:

  1. Checkout https://github.com/EngFlow/example/pull/243
  2. bazel build --config=remote_windows_x64 //cpp:cpp_lib (add --remote_executor and any other necessary flags).

Which operating system are you running Bazel on?

Windows Server 2022

What is the output of bazel info release?

release 6.3.2

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

n/a

What's the output of git remote get-url origin; git rev-parse master; git rev-parse HEAD ?

n/a

Is this a regression? If yes, please try to identify the Bazel commit where the bug was introduced.

No.

Have you found anything relevant by searching the web?

Issue #9172 - Windows: Bazel cannot share cpp cache between two projects with different workspace name

PR #9188 - Windows: Ignore workspace name differences while doing header checking

PR #13339 - Remote: Use execRoot as input root and do NOT set working directory by default.

Any other information, logs, or outputs that you want to share?

I spent the morning poking through the source code to figure out how this works. It looks like Bazel's CppCompile action is trying to validate that 1) headers included from srcs are in either srcs or direct dependencies' hdrs, and 2) headers are not included with absolute paths.

For MSVC, Bazel accomplishes that by enabling the /showincludes flag, which tells MSVC to print the path of each included file. The paths are absolute. The full output from one of these actions looks like this:

This line is the one that matters:

Note: including file: C:\worker\work\2\execroot\ws\cpp/hello.h

This is not hermetic. The path of the execroot could be anything. Here's it's C:\worker\work\2\execroot\ws. Normally it would be C:\worker\work\2\exec, but I've hacked it in this build to try and work around the issue (no luck).

In ShowIncludeFilter, Bazel uses a regular expression to replace everything up to .*execroot\\ with ../, so that turns into ../ws/cpp/hello.h. Later, that's joined with the local execroot within the workspace, so C:/_b/gjo2whp5/execroot/ws/cpp/hello.h, which is the path we see in the error message.

Bazel expects the path to be C:/_b/gjo2whp5/execroot/example/cpp/hello.h (example is the name of the workspace). Because it does not match, Bazel reports an error.

Tagging @meteorcloudy and @coeuvre who I think might have ideas on how to fix this. I'd be happy to work on this, but I'll need some guidance on what the solution should be and whether there's a good way to test it.

Guida contributor