bazel icon indicating copy to clipboard operation
bazel copied to clipboard

CppCompileAction: do not make declaredIncludeSrcs() part of the action key

Open obruns opened this issue 3 years ago • 10 comments

There are two types of input discovery in Bazel:

  • include scanning is hard-disabled [1]
  • depfile parsing is active and the action key is updated accordingly

However, due to declaredIncludeSrcs() being part of the action key, a change of the declared include srcs, either explicitly or via a glob(), causes a CppCompileAction to be re-executed even though none of its inputs (as reported by the compiler) had changed.

When an action does not discover inputs, there is no need to distinguish between inputs and declared inputs since the inputs already go into the cache key. When an action does discover inputs, the action key gets updated after parsing the depfile.

With this change, Bazel behaves much like Ninja in terms of avoiding unnecessary recompiles of C++ translation units.

There should probably be an entry in the release notes because this change makes existing cache entries non-candidates.

[1] https://github.com/bazelbuild/bazel/commit/1df4c71a9cf52f2dd24c4a10da75bb88631e7fde

Fixes: #8319 Hint-by: Lukacs T. Berki [email protected]

obruns avatar Jun 21 '21 15:06 obruns

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

google-cla[bot] avatar Jun 21 '21 15:06 google-cla[bot]

@googlebot I signed it!

obruns avatar Jun 21 '21 15:06 obruns

@oquenchil , can you take care of this? I have a little too much to do this week and the next :(

lberki avatar Jun 22 '21 09:06 lberki

I don't think this is going to work because this would probably break our internal tests for the reasons described here.

I can imagine two possible resolutions:

  • @oquenchil runs our internal presubmits on this change. If they pass, I got all this wrong. They are extensive enough that in that case, I'm comfortable merging this pull request.
  • You change this pull request to add getDeclaredIncludeSrcs() to the action key iff include scanning is enabled. Given that that means that internal behavior does not change, I'm fairly certain that it will not break anything at Google..

lberki avatar Jun 22 '21 12:06 lberki

Thanks for your feedback @lberki. I am happy to proceed with either of your proposals.

About the failing tests on Windows/msvc: /showIncludes and parsing should be enabled, AFAICT. I would have to look into why exactly those tests are failing on msvc. Unfortunately, I currently don't have a working Windows/msvc/Bazel setup. Therefore, I could:

  • Disable those test cases based on $is_windows which is already available in cpp_test.sh or
  • Spent some time setting things up and proceed with properly fixing those failures (not preferred)

obruns avatar Jun 22 '21 14:06 obruns

I agree that the original issue #8319 needs to be addressed. The priority right now is not the highest though, it doesn't happen that often that you add a new header. I will see if I have some time to properly look at this during Q3.

oquenchil avatar Jun 28 '21 08:06 oquenchil

@oquenchil and @lberki, can you give a status update? Do you still plan to have a closer look during Q3/2021? Thanks.

obruns avatar Aug 09 '21 14:08 obruns

@oquenchil ?

lberki avatar Aug 10 '21 06:08 lberki

No sorry, no time this quarter.

oquenchil avatar Aug 10 '21 11:08 oquenchil

Please consider the following test-case that starts failing with this change:

function test_compile_on_header_existence_check() {
  local -r pkg=$FUNCNAME
  mkdir -p $pkg
  cat > $pkg/BUILD <<EOF
cc_binary(name="a", srcs=["a.cc"], deps=["b"])
cc_library(name="b", includes=["."], hdrs=["b.h"])
EOF

  cat > $pkg/a.cc <<EOF
#include "b.h"

int main(void) {
  return 0;
}
EOF

  cat > $pkg/b.h <<EOF
#if __has_include("unused.h")
#error unused.h shall not exist
#endif  // __has_include("unused.h")
EOF

  bazel build -s //$pkg:a >& $TEST_log || fail "build failed"
  expect_log "Compiling $pkg/a.cc"

  cat > $pkg/BUILD <<EOF
cc_binary(name="a", srcs=["a.cc"], deps=["b"])
cc_library(name="b", includes=["."], hdrs=["b.h", "unused.h"])
EOF

  cat > $pkg/unused.h <<EOF
=== BANANA ===
EOF

  bazel build -s //$pkg:a >& $TEST_log && fail "unexpected success" || true
  expect_log "Compiling $pkg/a.cc"
}

See https://github.com/bazelbuild/bazel/issues/8319#issuecomment-976693110 for more context.

Edit: only tested with clang so far, gcc/msvc may not support __has_include

Yannic avatar Nov 23 '21 15:11 Yannic

Closing this PR. If still interested, please file an issue instead so that this is tackled in a different way. It should pass Yannic's test and internal tests.

oquenchil avatar Jan 20 '23 09:01 oquenchil