Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,11 @@ public NestedSet<Artifact> discoverInputs(ActionExecutionContext actionExecution
.setSystemIncludeDirs(systemIncludeDirs)
.setCmdlineIncludes(getCmdlineIncludes(options))
.setIsValidUndeclaredHeader(getValidUndeclaredHeaderPredicate())
// Register generated prunable/toolchain headers as declared so the include scanner
// can resolve them; it never stats output-directory paths. Keep in sync with the
// matching call in the rediscovery path below. See
// IncludeScanningHeaderData.Builder#addDeclaredHeaders.
.addDeclaredHeaders(additionalPrunableHeaders)
.build();
additionalInputs = findUsedHeaders(actionExecutionContext, includeScanningHeaderData);
if (additionalInputs == null) {
Expand Down Expand Up @@ -1910,6 +1915,11 @@ public NestedSet<Artifact> getInputFilesForExtraAction(
includeScanningHeaderData
.setSystemIncludeDirs(getSystemIncludeDirs())
.setCmdlineIncludes(getCmdlineIncludes(getCompilerOptions()))
// Register generated prunable/toolchain headers as declared so the include
// scanner can resolve them; it never stats output-directory paths. Keep in sync
// with the matching call in discoverInputs above. See
// IncludeScanningHeaderData.Builder#addDeclaredHeaders.
.addDeclaredHeaders(additionalPrunableHeaders)
.build());
if (usedHeaders == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,20 @@ public CppCompileAction buildAndVerify() throws UnconfiguredActionConfigExceptio
.addTransitive(cacheKeyInputs)
.build();
NestedSet<Artifact> prunableHeaders = additionalPrunableHeaders;
if (getShouldScanIncludes()) {
// With include scanning enabled, only compiler_files_without_includes is staged as a
// mandatory input; the rest of the toolchain files (compiler_files) are expected to be
// discovered on demand by the include scanner. Generated toolchain headers -- e.g. a
// sysroot whose headers are symlinked into the output tree -- are only discoverable if they
// are known inputs, so fold compiler_files into the prunable set here. They must also be
// registered as declared headers (the scanner never stats output-directory paths); see the
// addDeclaredHeaders calls in discoverInputs below.
prunableHeaders =
NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(additionalPrunableHeaders)
.addTransitive(ccToolchain.getCompilerFiles())
.build();
}

configuration.modifyExecutionInfo(
executionInfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
Expand Down Expand Up @@ -243,6 +244,28 @@ public Builder setIsValidUndeclaredHeader(
return this;
}

@CanIgnoreReturnValue
public Builder addDeclaredHeaders(NestedSet<Artifact> headers) {
// pathToDeclaredHeader is a fresh, per-action mutable CompactHashMap created by
// CcCompilationContext#createIncludeScanningHeaderData (which intentionally avoids the
// more expensive ImmutableMap). Mutating it in place here is therefore safe -- it is not
// shared across actions -- and consistent with that method's performance choice.
for (Artifact header : headers.toList()) {
// Only generated (output-directory) headers need to be registered here. Source
// headers already resolve via source-artifact lookup in the include scanner, so
// registering them would be redundant. Skipping them keeps this map empty for the
// common case of a source-file sysroot (e.g. GRTE), leaving those toolchains
// entirely unaffected. Tree artifacts are handled separately and are skipped.
if (!header.isSourceArtifact() && !header.isTreeArtifact()) {
// Use putIfAbsent so a header the target already declared for this exec path takes
// precedence: the target's own mapping is authoritative and must not be shadowed by
// a toolchain/prunable header that happens to share the path.
pathToDeclaredHeader.putIfAbsent(header.getExecPath(), header);
}
}
return this;
}

public IncludeScanningHeaderData build() {
return new IncludeScanningHeaderData(
pathToDeclaredHeader,
Expand Down
Loading