Skip to content

Commit 4c00ef2

Browse files
authored
Revert "[8.1.0] Add support for path mapping to CppArchive" (#25153)
Reverts #25146 Due to #25081 (comment)
1 parent 65621ac commit 4c00ef2

22 files changed

+184
-345
lines changed

src/main/java/com/google/devtools/build/lib/actions/AbstractCommandLine.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ public void addToFingerprint(
5656
CoreOptions.OutputPathsMode outputPathsMode,
5757
Fingerprint fingerprint)
5858
throws CommandLineExpansionException, InterruptedException {
59-
for (String s :
60-
arguments(/* artifactExpander= */ null, PathMapper.forActionKey(outputPathsMode))) {
59+
for (String s : arguments()) {
6160
fingerprint.addString(s);
6261
}
6362
}

src/main/java/com/google/devtools/build/lib/actions/BUILD

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,6 @@ java_library(
313313
"ArtifactRoot.java",
314314
"Artifacts.java",
315315
"PathMapper.java",
316-
"PathMapperConstants.java",
317316
],
318317
deps = [
319318
":action_lookup_data",
@@ -323,7 +322,6 @@ java_library(
323322
":commandline_item",
324323
":package_roots",
325324
"//src/main/java/com/google/devtools/build/docgen/annot",
326-
"//src/main/java/com/google/devtools/build/lib/analysis:config/core_options",
327325
"//src/main/java/com/google/devtools/build/lib/cmdline",
328326
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
329327
"//src/main/java/com/google/devtools/build/lib/collect/nestedset:fingerprint_cache",

src/main/java/com/google/devtools/build/lib/actions/PathMapper.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414

1515
package com.google.devtools.build.lib.actions;
1616

17+
import com.github.benmanes.caffeine.cache.Caffeine;
18+
import com.github.benmanes.caffeine.cache.LoadingCache;
1719
import com.google.devtools.build.docgen.annot.DocCategory;
1820
import com.google.devtools.build.lib.actions.CommandLineItem.ExceptionlessMapFn;
1921
import com.google.devtools.build.lib.actions.CommandLineItem.MapFn;
20-
import com.google.devtools.build.lib.analysis.config.CoreOptions;
2122
import com.google.devtools.build.lib.starlarkbuildapi.FileRootApi;
2223
import com.google.devtools.build.lib.vfs.PathFragment;
2324
import com.google.errorprone.annotations.CheckReturnValue;
@@ -44,7 +45,7 @@ public interface PathMapper {
4445
* {@link #storeIn(StarlarkSemantics)}.
4546
*/
4647
static PathMapper loadFrom(StarlarkSemantics semantics) {
47-
return semantics.get(PathMapperConstants.SEMANTICS_KEY);
48+
return semantics.get(SEMANTICS_KEY);
4849
}
4950

5051
/**
@@ -64,11 +65,10 @@ static PathMapper loadFrom(StarlarkSemantics semantics) {
6465
default StarlarkSemantics storeIn(StarlarkSemantics semantics) {
6566
// This in particular covers the case where the semantics do not have a path mapper yet and this
6667
// is NOOP.
67-
if (semantics.get(PathMapperConstants.SEMANTICS_KEY) == this) {
68+
if (semantics.get(SEMANTICS_KEY) == this) {
6869
return semantics;
6970
}
70-
return new StarlarkSemantics(
71-
semantics.toBuilder().set(PathMapperConstants.SEMANTICS_KEY, this).build()) {
71+
return new StarlarkSemantics(semantics.toBuilder().set(SEMANTICS_KEY, this).build()) {
7272
// The path mapper doesn't affect which fields or methods are available on any given Starlark
7373
// object; it just affects the behavior of certain methods on Artifact. We thus preserve the
7474
// original semantics as a cache key. Otherwise, even if PathMapper#equals returned true for
@@ -82,13 +82,6 @@ public StarlarkSemantics getStarlarkClassDescriptorCacheKey() {
8282
};
8383
}
8484

85-
/** Returns the instance to use during action key computation. */
86-
static PathMapper forActionKey(CoreOptions.OutputPathsMode outputPathsMode) {
87-
return outputPathsMode == CoreOptions.OutputPathsMode.OFF
88-
? NOOP
89-
: PathMapperConstants.FOR_FINGERPRINTING;
90-
}
91-
9285
/**
9386
* Returns the exec path with the path mapping applied.
9487
*
@@ -149,7 +142,7 @@ default FileRootApi mapRoot(Artifact artifact) {
149142
if (root.isSourceRoot()) {
150143
// Source roots' paths are never mapped, but we still need to wrap them in a
151144
// MappedArtifactRoot to ensure correct Starlark comparison behavior.
152-
return PathMapperConstants.mappedSourceRoots.get(root);
145+
return mappedSourceRoots.get(root);
153146
}
154147
// It would *not* be correct to just apply #map to the exec path of the root: The root part of
155148
// the mapped exec path of this artifact may depend on its complete exec path as well as on e.g.
@@ -199,6 +192,15 @@ public FileRootApi mapRoot(Artifact artifact) {
199192
}
200193
};
201194

195+
StarlarkSemantics.Key<PathMapper> SEMANTICS_KEY =
196+
new StarlarkSemantics.Key<>("path_mapper", PathMapper.NOOP);
197+
198+
// Not meant for use outside this interface.
199+
LoadingCache<ArtifactRoot, MappedArtifactRoot> mappedSourceRoots =
200+
Caffeine.newBuilder()
201+
.weakKeys()
202+
.build(sourceRoot -> new MappedArtifactRoot(sourceRoot.getExecPath()));
203+
202204
/** A {@link FileRootApi} returned by {@link PathMapper#mapRoot(Artifact)}. */
203205
@StarlarkBuiltin(
204206
name = "mapped_root",

src/main/java/com/google/devtools/build/lib/actions/PathMapperConstants.java

Lines changed: 0 additions & 81 deletions
This file was deleted.

src/main/java/com/google/devtools/build/lib/analysis/actions/PathMappers.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,49 @@
4040
* PathMapper}).
4141
*/
4242
public final class PathMappers {
43+
private static final PathFragment BAZEL_OUT = PathFragment.create("bazel-out");
44+
private static final PathFragment BLAZE_OUT = PathFragment.create("blaze-out");
45+
46+
/**
47+
* A special instance for use in {@link AbstractAction#computeKey} when path mapping is generally
48+
* enabled for an action.
49+
*
50+
* <p>When computing an action key, the following approaches to taking path mapping into account
51+
* do <b>not</b> work:
52+
*
53+
* <ul>
54+
* <li>Using the actual path mapper is prohibitive since constructing it requires checking for
55+
* collisions among the action input's paths when computing the action key, which flattens
56+
* the input depsets of all actions that opt into path mapping and also increases CPU usage.
57+
* <li>Unconditionally using {@link StrippingPathMapper} can result in stale action keys when an
58+
* action is opted out of path mapping at execution time due to input path collisions after
59+
* stripping. See path_mapping_test for an example.
60+
* <li>Using {@link PathMapper#NOOP} does not distinguish between map_each results built from
61+
* strings and those built from {@link
62+
* com.google.devtools.build.lib.starlarkbuildapi.FileApi#getExecPathStringForStarlark}.
63+
* While the latter will be mapped at execution time, the former won't, resulting in the
64+
* same digest for actions that behave differently at execution time. This is covered by
65+
* tests in StarlarkRuleImplementationFunctionsTest.
66+
* </ul>
67+
*
68+
* <p>Instead, we use a special path mapping instance that preserves the equality relations
69+
* between the original config segments, but prepends a fixed string to distinguish hard-coded
70+
* path strings from mapped paths. This relies on actions using path mapping to be "root
71+
* agnostic": they must not contain logic that depends on any particular (output) root path.
72+
*/
73+
private static final PathMapper FOR_FINGERPRINTING =
74+
execPath -> {
75+
if (!execPath.startsWith(BAZEL_OUT) && !execPath.startsWith(BLAZE_OUT)) {
76+
// This is not an output path.
77+
return execPath;
78+
}
79+
String execPathString = execPath.getPathString();
80+
int startOfConfigSegment = execPathString.indexOf('/') + 1;
81+
return PathFragment.createAlreadyNormalized(
82+
execPathString.substring(0, startOfConfigSegment)
83+
+ "pm-"
84+
+ execPathString.substring(startOfConfigSegment));
85+
};
4386

4487
// TODO: Remove actions from this list by adding ExecutionRequirements.SUPPORTS_PATH_MAPPING to
4588
// their execution info instead.
@@ -93,6 +136,13 @@ public static void addToFingerprint(
93136
}
94137
}
95138

139+
/** Returns the instance to use during action key computation. */
140+
public static PathMapper forActionKey(OutputPathsMode outputPathsMode) {
141+
return outputPathsMode == OutputPathsMode.OFF
142+
? PathMapper.NOOP
143+
: PathMappers.FOR_FINGERPRINTING;
144+
}
145+
96146
/**
97147
* Actions that support path mapping should call this method when creating their {@link Spawn}.
98148
*

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkCustomCommandLine.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.google.devtools.build.lib.actions.FilesetOutputTree.RelativeSymlinkBehaviorWithoutError;
4242
import com.google.devtools.build.lib.actions.PathMapper;
4343
import com.google.devtools.build.lib.actions.SingleStringArgFormatter;
44+
import com.google.devtools.build.lib.analysis.actions.PathMappers;
4445
import com.google.devtools.build.lib.analysis.config.CoreOptions;
4546
import com.google.devtools.build.lib.cmdline.Label;
4647
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
@@ -574,7 +575,7 @@ private int addToFingerprint(
574575
maybeExpandDirectories(
575576
artifactExpander,
576577
arguments.subList(argi, argi + count),
577-
PathMapper.forActionKey(outputPathsMode));
578+
PathMappers.forActionKey(outputPathsMode));
578579
argi += count;
579580
if (mapEach != null) {
580581
// TODO(b/160181927): If artifactExpander == null (which happens in the analysis phase)
@@ -589,7 +590,7 @@ private int addToFingerprint(
589590
fingerprint::addString,
590591
location,
591592
artifactExpander,
592-
PathMapper.forActionKey(outputPathsMode),
593+
PathMappers.forActionKey(outputPathsMode),
593594
starlarkSemantics);
594595
} else {
595596
for (Object value : maybeExpandedValues) {
@@ -1204,7 +1205,7 @@ public void expandToCommandLine(Object object, Consumer<String> args)
12041205
args,
12051206
location,
12061207
artifactExpander,
1207-
PathMapper.forActionKey(outputPathsMode),
1208+
PathMappers.forActionKey(outputPathsMode),
12081209
starlarkSemantics);
12091210
}
12101211

@@ -1214,7 +1215,7 @@ private List<Object> maybeExpandDirectory(Object object) throws CommandLineExpan
12141215
}
12151216

12161217
return VectorArg.expandDirectories(
1217-
artifactExpander, ImmutableList.of(object), PathMapper.forActionKey(outputPathsMode));
1218+
artifactExpander, ImmutableList.of(object), PathMappers.forActionKey(outputPathsMode));
12181219
}
12191220

12201221
@Override

src/main/java/com/google/devtools/build/lib/rules/cpp/CcStarlarkInternal.java

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -105,40 +105,24 @@ public CcToolchainVariables getCcToolchainVariables(Dict<?, ?> buildVariables)
105105

106106
CcToolchainVariables.Builder ccToolchainVariables = CcToolchainVariables.builder();
107107
for (var entry : buildVariables.entrySet()) {
108-
String key = (String) entry.getKey();
109-
Object value = entry.getValue();
110-
switch (value) {
111-
case String s -> ccToolchainVariables.addStringVariable(key, s);
112-
case Artifact a -> ccToolchainVariables.addArtifactVariable(key, a);
113-
case Boolean b -> ccToolchainVariables.addBooleanValue(key, b);
114-
case Iterable<?> values -> {
115-
if (key.equals("libraries_to_link")) {
116-
SequenceBuilder sb = new SequenceBuilder();
117-
for (var v : (Iterable<VariableValue>) values) {
118-
sb.addValue(v);
119-
}
120-
ccToolchainVariables.addCustomBuiltVariable(key, sb);
121-
} else {
122-
ccToolchainVariables.addStringSequenceVariable(key, (Iterable<String>) values);
108+
if (entry.getValue() instanceof String) {
109+
ccToolchainVariables.addStringVariable((String) entry.getKey(), (String) entry.getValue());
110+
} else if (entry.getValue() instanceof Boolean) {
111+
ccToolchainVariables.addBooleanValue((String) entry.getKey(), (Boolean) entry.getValue());
112+
} else if (entry.getValue() instanceof Iterable<?>) {
113+
if (entry.getKey().equals("libraries_to_link")) {
114+
SequenceBuilder sb = new SequenceBuilder();
115+
for (var value : (Iterable<?>) entry.getValue()) {
116+
sb.addValue((VariableValue) value);
123117
}
118+
ccToolchainVariables.addCustomBuiltVariable((String) entry.getKey(), sb);
119+
} else {
120+
ccToolchainVariables.addStringSequenceVariable(
121+
(String) entry.getKey(), (Iterable<String>) entry.getValue());
124122
}
125-
case Depset depset -> {
126-
Class<?> type = depset.getElementClass();
127-
// Type doesn't matter for empty depsets.
128-
if (type == String.class || type == null) {
129-
ccToolchainVariables.addStringSequenceVariable(key, depset.getSet(String.class));
130-
} else if (type == Artifact.class) {
131-
ccToolchainVariables.addArtifactSequenceVariable(key, depset.getSet(Artifact.class));
132-
} else if (type == PathFragment.class) {
133-
ccToolchainVariables.addPathFragmentSequenceVariable(
134-
key, depset.getSet(PathFragment.class));
135-
} else {
136-
throw new IllegalStateException("Unexpected depset element type: %s".formatted(type));
137-
}
138-
}
139-
default ->
140-
throw new IllegalStateException(
141-
"Unexpected value: %s (%s)".formatted(value, value.getClass()));
123+
} else if (entry.getValue() instanceof Depset) {
124+
ccToolchainVariables.addStringSequenceVariable(
125+
(String) entry.getKey(), ((Depset) entry.getValue()).getSet(String.class));
142126
}
143127
}
144128
return ccToolchainVariables.build();

src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,18 +412,18 @@ private boolean canBeExpanded(
412412
}
413413
if (expandIfTrue != null
414414
&& (!variables.isAvailable(expandIfTrue, expander)
415-
|| !variables.getVariable(expandIfTrue, pathMapper).isTruthy())) {
415+
|| !variables.getVariable(expandIfTrue).isTruthy())) {
416416
return false;
417417
}
418418
if (expandIfFalse != null
419419
&& (!variables.isAvailable(expandIfFalse, expander)
420-
|| variables.getVariable(expandIfFalse, pathMapper).isTruthy())) {
420+
|| variables.getVariable(expandIfFalse).isTruthy())) {
421421
return false;
422422
}
423423
if (expandIfEqual != null
424424
&& (!variables.isAvailable(expandIfEqual.variable, expander)
425425
|| !variables
426-
.getVariable(expandIfEqual.variable, pathMapper)
426+
.getVariable(expandIfEqual.variable)
427427
.getStringValue(expandIfEqual.variable, pathMapper)
428428
.equals(expandIfEqual.value))) {
429429
return false;

0 commit comments

Comments
 (0)