header files of dependent cc_libraries should only be copied to sandbox if they are added to srcs.
i noticed that private header files are copied to sandboxes and producing rebuilds of of dependen cc_* targets.
BUILD.bazel:
cc_library(
name = "a",
srcs = ["a.h"],
)
cc_binary(
name = "b",
srcs = ["b.c"],
deps = [":a"],
)
a.h:
#define FOO 1
b.c:
#include "a.h"
int main(void) {
return FOO;
}
This should not compile with sandbox execution. Changes in a.h should also not trigger a rebuild of b.c.
MacOS
bazel info release?release 0.18.1-homebrew
@scentini whats the status of that issue? Why was untriaged removed?
Hi there,
The untriaged is removed because this issue now has an assignee.
However, I haven't gotten to it just yet, so there is no progress.
@scentini could you add a priority to this issue, please?
Hi, sorry for the delayed response.
I will close this issue as we are aware of it but don't have immediate plans to fix it.
For this we need to implement modules, which is planned somewhere along the road, but we're not there yet.
The problem I face is that a change to a private header of a base library like abseil triggers a complete rebuilt and re-test of the tree.
Why do you need C++ modules to fix the issue? To me it seems that the implicitly formulated dependencies are the problem.
Is that private header included from a public header? Was it a clean build or a incremental build with a running Bazel server?
We use .d files to remove inputs that didn't contribute to the compilation. From that I extrapolate that your private header was actually used during compilation, and it is affecting its outputs. We don't propagate the change further up the graph when action outputs didn't change even though it's inputs have changed. From that I extrapolate that the rebuild of the tree was actually correct thing to do.
If my extrapolations don't correlate with the reality, it might be a bug. Do you have a small repro repo I can play with? Does it only behave this way on mac or also on linux?
Modules are what we use to implement layering checks (that headers included are properly depended on). I thought you care about private headers from the visibility perspective, that you want to prevent others from including the header. After your last comment I see you care about invalidation, so the modules/layering check is irrelevant.
I think the issue is that the behaviour of cc_library is inconsistent with the specs https://docs.bazel.build/versions/master/be/c-cpp.html#hdrs
Taking a snippet of the given example
cc_library(
name = "bar",
srcs = [
"bar.cc",
"bar-impl.h",
],
hdrs = ["bar.h"],
deps = [":baz"],
)
cc_library(
name = "baz",
srcs = [
"baz.cc",
"baz-impl.h",
],
hdrs = ["baz.h"],
)
The problem that OP (probably) and I have experienced is that bar.h, bar.cc, and bar-impl.h can all include baz-impl.h, even though baz-impl.h is in the srcs list of baz. According to the documentation, only baz.h (being a hdr) should be visible to bar.h, bar.cc, and bar-impl.h, and none of the srcs should be exposed outside of the cc_library
Most helpful comment
The problem I face is that a change to a private header of a base library like abseil triggers a complete rebuilt and re-test of the tree.
Why do you need C++ modules to fix the issue? To me it seems that the implicitly formulated dependencies are the problem.