bazel: Bazel + MSVC C++ = missing dependency declarations [culprit #5136]

Description of the problem / feature request:

We are getting a spurious this rule is missing dependency declarations for the following files included by ... when using MSVC to build on Windows. I say it is spurious because the same command works correctly on Linux and OSX, and I’ve verified the BUILD rule is correct.

Bugs: what’s the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

On Windows + MSVC:

git clone https://github.com/abseil/abseil-cpp.git
bazel test --define absl=1 absl/...

The --define absl=1 part makes Google Test use Abseil. So Abseil tests uses Google Test, which in turn uses the Abseil libraries. I’m not sure if the circular project dependency has anything to do with this. Everything works as expected without --define absl=1.

Output on my machine:

PS C:\Users\dmauro\abseil-cpp> bazel --bazelrc=/dev/null test --define absl=1 absl/...
Loading:
Loading: 0 packages loaded
INFO: Build options have changed, discarding analysis cache.
Analyzing: 157 targets (16 packages loaded)
INFO: Analysed 157 targets (34 packages loaded).
INFO: Found 55 targets and 102 test targets...
[0 / 11] [-----] Creating source manifest for //absl/strings:ascii_test
[10 / 33] Compiling external/com_google_absl/absl/strings/charconv.cc; 1s local ... (4 actions running)
[15 / 33] Compiling external/com_google_absl/absl/strings/substitute.cc; 1s local ... (4 actions, 3 running)
[19 / 33] Compiling external/com_google_absl/absl/strings/str_cat.cc; 1s local ... (4 actions, 3 running)
[24 / 38] Compiling external/com_google_absl/absl/strings/str_replace.cc; 1s local ... (3 actions running)
[36 / 55] Compiling external/com_google_absl/absl/debugging/failure_signal_handler.cc; 0s local ... (4 actions running)
[39 / 58] Compiling external/com_google_absl/absl/debugging/failure_signal_handler.cc; 1s local ... (4 actions running)
[45 / 66] Compiling absl/base/internal/spinlock.cc; 1s local ... (4 actions, 3 running)
[54 / 78] Compiling external/com_google_absl/absl/base/internal/low_level_alloc.cc; 1s local ... (4 actions running)
[55 / 79] Compiling external/com_google_googletest/googletest/src/gtest-death-test.cc; 2s local ... (4 actions running)
[60 / 84] Compiling external/com_google_googletest/googletest/src/gtest.cc; 2s local ... (3 actions running)
[64 / 89] Compiling external/com_google_googletest/googletest/src/gtest-printers.cc; 2s local ... (4 actions running)
[73 / 98] Compiling absl/strings/str_replace.cc; 1s local ... (4 actions running)
[86 / 113] Compiling external/com_google_absl/absl/base/internal/spinlock.cc; 1s local ... (4 actions running)
ERROR: C:/users/dmauro/abseil-cpp/absl/strings/BUILD.bazel:148:1: undeclared inclusion(s) in rule '//absl/strings:ascii_
test':
this rule is missing dependency declarations for the following files included by 'absl/strings/ascii_test.cc':
  'absl/types/optional.h'
  'absl/utility/utility.h'
  'absl/types/bad_optional_access.h'
  'absl/types/variant.h'
  'absl/types/internal/variant.h'
  'absl/types/bad_variant_access.h'
INFO: Elapsed time: 29.078s, Critical Path: 4.50s
INFO: 71 processes: 71 local.
FAILED: Build did NOT complete successfully

It’s interesting that I see both Compiling absl/base/internal/spinlock.cc; and external/com_google_absl/absl/base/internal/low_level_alloc.cc; (note the external/com_google_absl prefix). It is as if Bazel doesn’t understand that the root WORKSPACE, named com_google_absl, isn’t the same Abseil that Google Test depends on, even though it depends on Abseil under the name com_google_absl. A Linux build never shows the external/com_google_absl in the output.

What operating system are you running Bazel on?

Windows 2008 R2 on GCP. I also tried it on a Kokoro instance (not sure of the Windows version of that) and got the same result.

What’s the output of bazel info release?

PS C:\Users\dmauro\abseil-cpp> bazel version
Build label: 0.15.0
Build target: bazel-out/x64_windows-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Tue Jun 26 12:09:42 2018 (1530014982)
Build timestamp: 1530014982
Build timestamp as int: 1530014982
PS C:\Users\dmauro\abseil-cpp> bazel info release
release 0.15.0

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

PS C:\Users\dmauro\abseil-cpp> git remote get-url origin ; git rev-parse master ; git rev-parse HEAD
https://github.com/abseil/abseil-cpp.git
2c5af55ed34850d8b7dd46177c8ca53fdfda920e
2c5af55ed34850d8b7dd46177c8ca53fdfda920e

Have you found anything relevant by searching the web?

https://github.com/bazelbuild/bazel/issues/5087 is possibly the same issue, but I’m not sure. That issue refers to remote workers.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 37 (29 by maintainers)

Commits related to this issue

Most upvoted comments

@derekmauro I’ve debugged on this and found the root cause. Let me explain how this issue happened on Windows and not on Linux.

  • First, the google test framework depends on a certain version of absel. See https://github.com/google/googletest/blob/master/WORKSPACE. Bazel downloads it as an external repository, that’s why external/com_google_absl/absl/... exists. It will be compiled when enabling define absl=1. This is also true on Linux.
$ bazel query 'somepath(//absl/strings:ascii_test, @com_google_absl//absl/types:optional)'
//absl/strings:ascii_test
@com_google_googletest//:gtest_main
@com_google_googletest//:gtest
@com_google_absl//absl/types:optional
  • When compiling absl/strings/ascii_test.cc, two include directories will be added - . and external/com_google_absl. Both directories contains absl/types/optional.h and other header files. The first one will be detected by the compiler, but only the second one is declared as dependency of the test. The dependency check thus failed.
  • It didn’t happen on Linux because sandbox is enabled by default. Since absl/types/optional.h is not declared as dependency, the compiler won’t see it. If you build with --spawn_strategy=standalone, you’ll get the same error as Windows.

@dslomov Is there anyway to override @com_google_absl in googletest to point to the local absl repository ?

Inspired by @laszlocsomor’s solution:

In a WORKSPACE, specify Abseil and GoogleTest as [new_]local_repository or [new_]http_archive (so neither Abseil nor GoogleTest is the main repo __main__) (*), then run bazel test --define absl=1 @com_google_absl//absl/base/.... All tests pass.

I believe (*) is how most Bazel users consume Abseil and GoogleTest (main repo is user’s own code). This solution should enable Abseil team to continue their work without breaking existing Abseil and GoogleTest users.