aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
diff options
context:
space:
mode:
authorGravatar Philipp Wollermann <philwo@google.com>2015-10-26 14:23:11 +0000
committerGravatar Florian Weikert <fwe@google.com>2015-10-27 11:46:59 +0000
commite42275c03a1978f4eb5aa97e6a4929606e97bed8 (patch)
tree729ca2d44892d024cfa7e3652b4e017343b66ed3 /src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
parent3e46cab997116e6b0a7a40428a414a53f5d7f9a3 (diff)
Refactor include scanning / .d file parsing in the C++ rules so that validating includes and updating action inputs is clearly separated and easier to understand now.
-- MOS_MIGRATED_REVID=106298050
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java80
1 files changed, 53 insertions, 27 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 9c292e3ce3..d486975c93 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -51,6 +51,7 @@ import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
+import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext.Reply;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
import com.google.devtools.build.lib.util.DependencySet;
import com.google.devtools.build.lib.util.FileType;
@@ -314,6 +315,16 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
return builder.build();
}
+ /**
+ * Whether we should do "include scanning". Note that this does *not* mean whether we should parse
+ * the .d files to determine which include files were used during compilation. Instead, this means
+ * whether we should a) run the pre-execution include scanner (see {@code IncludeScanningContext})
+ * if one exists and b) whether the action inputs should be modified to match the results of that
+ * pre-execution scanning and (if enabled) again after execution to match the results of the .d
+ * file parsing.
+ *
+ * <p>This does *not* have anything to do with "hdrs_check".
+ */
public boolean shouldScanIncludes() {
return shouldScanIncludes;
}
@@ -662,12 +673,10 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
*/
@VisibleForTesting
public void validateInclusions(
- MiddlemanExpander middlemanExpander, EventHandler eventHandler)
+ Iterable<Artifact> inputsForValidation,
+ MiddlemanExpander middlemanExpander,
+ EventHandler eventHandler)
throws ActionExecutionException {
- if (!shouldScanIncludes() || !inputsKnown()) {
- return;
- }
-
IncludeProblems errors = new IncludeProblems();
IncludeProblems warnings = new IncludeProblems();
Set<Artifact> allowedIncludes = new HashSet<>();
@@ -688,7 +697,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
Set<PathFragment> declaredIncludeDirs = Sets.newHashSet(context.getDeclaredIncludeDirs());
Set<PathFragment> warnIncludeDirs = Sets.newHashSet(context.getDeclaredIncludeWarnDirs());
Set<Artifact> declaredIncludeSrcs = Sets.newHashSet(context.getDeclaredIncludeSrcs());
- for (Artifact input : getInputs()) {
+ for (Artifact input : inputsForValidation) {
if (context.getCompilationPrerequisites().contains(input)
|| allowedIncludes.contains(input)) {
continue; // ignore our fixed source in mandatoryInput: we just want includes
@@ -811,12 +820,8 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
*/
@VisibleForTesting
@ThreadCompatible
- public final synchronized void updateActionInputs(Path execRoot,
- ArtifactResolver artifactResolver, CppCompileActionContext.Reply reply)
+ public final synchronized void updateActionInputs(NestedSet<Artifact> discoveredInputs)
throws ActionExecutionException {
- if (!shouldScanIncludes()) {
- return;
- }
inputsKnown = false;
NestedSetBuilder<Artifact> inputs = NestedSetBuilder.stableOrder();
Profiler.instance().startTask(ProfilerTask.ACTION_UPDATE, this);
@@ -826,7 +831,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
inputs.add(optionalSourceFile);
}
inputs.addAll(context.getCompilationPrerequisites());
- populateActionInputs(execRoot, artifactResolver, reply, inputs);
+ inputs.addTransitive(discoveredInputs);
inputsKnown = true;
} finally {
Profiler.instance().completeTask(ProfilerTask.ACTION_UPDATE);
@@ -853,27 +858,23 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
}
/**
- * Populates the given ordered collection with additional input artifacts
- * relevant to the specific action implementation.
- *
- * <p>The default implementation updates this Action's input set by reading
- * dynamically-discovered dependency information out of the .d file.
+ * Returns a collection with additional input artifacts relevant to the action by reading the
+ * dynamically-discovered dependency information from the .d file after the action has run.
*
* <p>Artifacts are considered inputs but not "mandatory" inputs.
*
- *
* @param reply the reply from the compilation.
- * @param inputs the ordered collection of inputs to append to
- * @throws ActionExecutionException iff the .d is missing (when required),
- * malformed, or has unresolvable included artifacts.
+ * @throws ActionExecutionException iff the .d is missing (when required), malformed, or has
+ * unresolvable included artifacts.
*/
+ @VisibleForTesting
@ThreadCompatible
- private void populateActionInputs(Path execRoot,
- ArtifactResolver artifactResolver, CppCompileActionContext.Reply reply,
- NestedSetBuilder<Artifact> inputs)
+ public NestedSet<Artifact> discoverInputsFromDotdFiles(
+ Path execRoot, ArtifactResolver artifactResolver, Reply reply)
throws ActionExecutionException {
+ NestedSetBuilder<Artifact> inputs = NestedSetBuilder.stableOrder();
if (getDotdFile() == null) {
- return;
+ return inputs.build();
}
try {
// Read .d file.
@@ -929,6 +930,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
// Some kind of IO or parse exception--wrap & rethrow it to stop the build.
throw new ActionExecutionException("error while parsing .d file", e, this, false);
}
+ return inputs.build();
}
@Override
@@ -1097,10 +1099,34 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
executor.getVerboseFailures(), this);
}
ensureCoverageNotesFilesExist();
+
+ // This is the .d file scanning part.
IncludeScanningContext scanningContext = executor.getContext(IncludeScanningContext.class);
- updateActionInputs(executor.getExecRoot(), scanningContext.getArtifactResolver(), reply);
+ NestedSet<Artifact> discoveredInputs =
+ discoverInputsFromDotdFiles(
+ executor.getExecRoot(), scanningContext.getArtifactResolver(), reply);
reply = null; // Clear in-memory .d files early.
- validateInclusions(actionExecutionContext.getMiddlemanExpander(), executor.getEventHandler());
+
+ // Post-execute "include scanning", which modifies the action inputs to match what the compile
+ // action actually used by incorporating the results of .d file parsing.
+ //
+ // We enable this when "include scanning" itself is enabled, or when hdrs_check is set to loose
+ // or warn, as otherwise the action might be missing inputs that the compiler used and rebuilds
+ // become incorrect.
+ //
+ // Note that this effectively disables post-execute "include scanning" in Bazel, because
+ // hdrs_check is forced to "strict" and "include scanning" is forced to off.
+ boolean usesStrictHdrsChecks = context.getDeclaredIncludeDirs().isEmpty()
+ && context.getDeclaredIncludeWarnDirs().isEmpty();
+ if (shouldScanIncludes() || !usesStrictHdrsChecks) {
+ updateActionInputs(discoveredInputs);
+ }
+
+ // hdrs_check: This cannot be switched off, because doing so would allow for incorrect builds.
+ validateInclusions(
+ discoveredInputs,
+ actionExecutionContext.getMiddlemanExpander(),
+ executor.getEventHandler());
}
/**