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;