diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
index 4156175bb45ad1..fc80892106b255 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
@@ -321,6 +321,11 @@ public boolean isVolatile() {
return false;
}
+ @Override
+ public boolean isShareable() {
+ return true;
+ }
+
@Override
public boolean showsOutputUnconditionally() {
return false;
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionAnalysisMetadata.java b/src/main/java/com/google/devtools/build/lib/actions/ActionAnalysisMetadata.java
index d86224ba3f0879..d39d7a5bff2eb8 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionAnalysisMetadata.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionAnalysisMetadata.java
@@ -30,6 +30,14 @@ public interface ActionAnalysisMetadata {
*/
ActionOwner getOwner();
+ /**
+ * Returns true if the action can be shared, i.e. multiple configured targets can create the same
+ * action.
+ *
+ *
In theory, these should not exist, but in practice, they do.
+ */
+ boolean isShareable();
+
/**
* Returns a mnemonic (string constant) for this kind of action; written into
* the master log so that the appropriate parser can be invoked for the output
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Actions.java b/src/main/java/com/google/devtools/build/lib/actions/Actions.java
index a3a6ba6b58049f..4e9fb5efbf4ed0 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Actions.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Actions.java
@@ -58,6 +58,10 @@ public final class Actions {
*/
public static boolean canBeShared(
ActionKeyContext actionKeyContext, ActionAnalysisMetadata a, ActionAnalysisMetadata b) {
+ if (!a.isShareable() || !b.isShareable()) {
+ return false;
+ }
+
if (!a.getMnemonic().equals(b.getMnemonic())) {
return false;
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java
index fcb17661766f6d..ab54b4f9f46ab4 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java
@@ -155,6 +155,11 @@ public ActionOwner getOwner() {
return actionOwner;
}
+ @Override
+ public boolean isShareable() {
+ return true;
+ }
+
@Override
public final String getMnemonic() {
return mnemonic;
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 dec074a50fca0a..443adde1ffc248 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
@@ -104,6 +104,7 @@ public class CppCompileAction extends AbstractAction
private final NestedSet additionalPrunableHeaders;
@Nullable private final Artifact grepIncludes;
+ private final boolean shareable;
private final boolean shouldScanIncludes;
private final boolean shouldPruneModules;
private final boolean usePic;
@@ -200,6 +201,7 @@ public class CppCompileAction extends AbstractAction
CcToolchainVariables variables,
Artifact sourceFile,
CppConfiguration cppConfiguration,
+ boolean shareable,
boolean shouldScanIncludes,
boolean shouldPruneModules,
boolean usePic,
@@ -236,6 +238,7 @@ public class CppCompileAction extends AbstractAction
Preconditions.checkArgument(!shouldPruneModules || shouldScanIncludes);
this.outputFile = Preconditions.checkNotNull(outputFile);
this.sourceFile = sourceFile;
+ this.shareable = shareable;
this.cppConfiguration = cppConfiguration;
// We do not need to include the middleman artifact since it is a generated artifact and will
// definitely exist prior to this action execution.
@@ -983,6 +986,11 @@ public ResourceSet estimateResourceConsumptionLocal() {
/* memoryMb= */ 200, /* cpuUsage= */ 0.5, /* ioUsage= */ 0.0);
}
+ @Override
+ public boolean isShareable() {
+ return shareable;
+ }
+
@Override
public void computeKey(ActionKeyContext actionKeyContext, Fingerprint fp) {
fp.addUUID(actionClassId);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
index 000eca845bab77..4ac5cc9395661e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
@@ -50,6 +50,7 @@ public class CppCompileActionBuilder {
public static final UUID GUID = UUID.fromString("97493805-894f-493a-be66-9a698f45c31d");
private final ActionOwner owner;
+ private boolean shareable;
private final BuildConfiguration configuration;
private CcToolchainFeatures.FeatureConfiguration featureConfiguration;
private CcToolchainVariables variables = CcToolchainVariables.EMPTY;
@@ -112,6 +113,7 @@ private CppCompileActionBuilder(
CcToolchainProvider ccToolchain,
@Nullable Artifact grepIncludes) {
this.owner = actionOwner;
+ this.shareable = false;
this.configuration = configuration;
this.cppConfiguration = configuration.getFragment(CppConfiguration.class);
this.mandatoryInputsBuilder = NestedSetBuilder.stableOrder();
@@ -128,6 +130,7 @@ private CppCompileActionBuilder(
*/
public CppCompileActionBuilder(CppCompileActionBuilder other) {
this.owner = other.owner;
+ this.shareable = other.shareable;
this.featureConfiguration = other.featureConfiguration;
this.sourceFile = other.sourceFile;
this.mandatoryInputsBuilder = NestedSetBuilder.stableOrder()
@@ -304,6 +307,7 @@ public CppCompileAction buildAndVerify(Consumer errorCollector) {
variables,
sourceFile,
cppConfiguration,
+ shareable,
shouldScanIncludes,
shouldPruneModules(),
usePic,
@@ -331,6 +335,7 @@ public CppCompileAction buildAndVerify(Consumer errorCollector) {
variables,
sourceFile,
cppConfiguration,
+ shareable,
shouldScanIncludes,
shouldPruneModules(),
usePic,
@@ -597,6 +602,11 @@ public CppCompileActionBuilder setSemantics(CppSemantics semantics) {
return this;
}
+ public CppCompileActionBuilder setShareable(boolean shareable) {
+ this.shareable = shareable;
+ return this;
+ }
+
public CppCompileActionBuilder setShouldScanIncludes(boolean shouldScanIncludes) {
this.shouldScanIncludes = shouldScanIncludes;
return this;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionTemplate.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionTemplate.java
index c1838770a0d389..7b2a75296966b8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionTemplate.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionTemplate.java
@@ -188,6 +188,11 @@ public ActionOwner getOwner() {
return actionOwner;
}
+ @Override
+ public boolean isShareable() {
+ return false;
+ }
+
@Override
public final String getMnemonic() {
return "CppCompileActionTemplate";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkstampCompileHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkstampCompileHelper.java
index 2fef0206663c66..1e5244722aeb1a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkstampCompileHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkstampCompileHelper.java
@@ -75,6 +75,7 @@ public static CppCompileAction createLinkstampCompileAction(
.setBuiltinIncludeFiles(buildInfoHeaderArtifacts)
.addMandatoryInputs(nonCodeInputs)
.setCppConfiguration(cppConfiguration)
+ .setShareable(true)
.setShouldScanIncludes(false)
.setActionName(CppActionNames.LINKSTAMP_COMPILE);
semantics.finalizeCompileActionBuilder(ruleContext, builder);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
index 362ada187888f6..f848d6581b321d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
@@ -63,6 +63,7 @@ public class FakeCppCompileAction extends CppCompileAction {
CcToolchainVariables variables,
Artifact sourceFile,
CppConfiguration cppConfiguration,
+ boolean shareable,
boolean shouldScanIncludes,
boolean shouldPruneModules,
boolean usePic,
@@ -88,6 +89,7 @@ public class FakeCppCompileAction extends CppCompileAction {
variables,
sourceFile,
cppConfiguration,
+ shareable,
shouldScanIncludes,
shouldPruneModules,
usePic,
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java b/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java
index 4d25bde4cb99bd..233efc0b9a7227 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java
@@ -483,6 +483,11 @@ public ActionOwner getOwner() {
throw new IllegalStateException();
}
+ @Override
+ public boolean isShareable() {
+ throw new IllegalStateException();
+ }
+
@Override
public String prettyPrint() {
throw new IllegalStateException();
diff --git a/src/test/java/com/google/devtools/build/lib/exec/util/FakeOwner.java b/src/test/java/com/google/devtools/build/lib/exec/util/FakeOwner.java
index aaf7197819c7de..49bb3f83991d4d 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/util/FakeOwner.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/util/FakeOwner.java
@@ -59,6 +59,11 @@ public ActionOwner getOwner() {
null);
}
+ @Override
+ public boolean isShareable() {
+ return false;
+ }
+
@Override
public String getMnemonic() {
return mnemonic;