Skip to content

Commit ceb9955

Browse files
gregestrencopybara-github
authored andcommitted
Adjust --top_level_targets_for_symlinks
Adjust `--top_level_targets_for_symlinks`. #### Old semantics: - If all targets in `$ bazel build //...` have the top-level config, `bazel-bin`, etc. point to that config - If all targets in `$ bazel build //...` have the same transitioned config, `bazel-bin`, etc. point to that config - If targets in `$ bazel build //...` have mixed configs, `bazel-bin`, etc. are deleted #### New semantics: - If all targets in `$ bazel build //...` have the top-level config, `bazel-bin`, etc. point to that config - If all targets in `$ bazel build //...` have the same transitioned config, `bazel-bin`, etc. point to that config - If targets in `$ bazel build //...` have mixed configs and at least one of them is the top-level config, `bazel-bin`, etc. point to the top-level config - If targets in `$ bazel build //...` have mixed configs and none are the top-level config, `bazel-bin`, etc. are deleted Fixes #17081. Closes #18854. PiperOrigin-RevId: 546938509 Change-Id: I75adf0b8c2094522125c5e65d8c450eb2436d392
1 parent 78cd6fc commit ceb9955

File tree

3 files changed

+83
-15
lines changed

3 files changed

+83
-15
lines changed

src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -766,16 +766,39 @@ private ImmutableList<ConvenienceSymlink> createConvenienceSymlinks(
766766
Reporter reporter = env.getReporter();
767767

768768
// Gather configurations to consider.
769-
Set<BuildConfigurationValue> targetConfigurations =
770-
buildRequestOptions.useTopLevelTargetsForSymlinks() && !targetsToBuild.isEmpty()
771-
? targetsToBuild.stream()
772-
.map(ConfiguredTarget::getActual)
773-
.map(ConfiguredTarget::getConfigurationKey)
774-
.filter(Objects::nonNull)
775-
.distinct()
776-
.map((key) -> executor.getConfiguration(reporter, key))
777-
.collect(toImmutableSet())
778-
: ImmutableSet.of(configuration);
769+
ImmutableSet<BuildConfigurationValue> targetConfigs;
770+
if (buildRequestOptions.useTopLevelTargetsForSymlinks() && !targetsToBuild.isEmpty()) {
771+
// Collect the configuration of each top-level requested target. These may be different than
772+
// the build's top-level configuration because of self-transitions.
773+
ImmutableSet<BuildConfigurationValue> requestedTargetConfigs =
774+
targetsToBuild.stream()
775+
.map(ConfiguredTarget::getActual)
776+
.map(ConfiguredTarget::getConfigurationKey)
777+
.filter(Objects::nonNull)
778+
.distinct()
779+
.map((key) -> executor.getConfiguration(reporter, key))
780+
.collect(toImmutableSet());
781+
if (requestedTargetConfigs.size() == 1) {
782+
// All top-level targets have the same configuration, so use that one.
783+
targetConfigs = requestedTargetConfigs;
784+
} else if (requestedTargetConfigs.stream()
785+
.anyMatch(
786+
c -> c.getOutputDirectoryName().equals(configuration.getOutputDirectoryName()))) {
787+
// Mixed configs but at least one matches the top-level config's output path (this doesn't
788+
// mean it's the same as the top-level config: --trim_test_configuration means non-test
789+
// targets use the default output path but lack the top-level config's TestOptions). Set
790+
// symlinks to the top-level config so at least non-transitioned targets resolve. See
791+
// https://github.com/bazelbuild/bazel/issues/17081.
792+
targetConfigs = ImmutableSet.of(configuration);
793+
} else {
794+
// Mixed configs, none of which include the top-level config. Delete the symlinks because
795+
// they won't contain any relevant data. This is handled in the
796+
// createOutputDirectorySymlinks call below.
797+
targetConfigs = requestedTargetConfigs;
798+
}
799+
} else {
800+
targetConfigs = ImmutableSet.of(configuration);
801+
}
779802

780803
String productName = runtime.getProductName();
781804
try (SilentCloseable c =
@@ -787,7 +810,7 @@ private ImmutableList<ConvenienceSymlink> createConvenienceSymlinks(
787810
env.getWorkspace(),
788811
env.getDirectories(),
789812
getReporter(),
790-
targetConfigurations,
813+
targetConfigs,
791814
options -> getConfiguration(executor, reporter, options),
792815
productName);
793816
}

src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ static ImmutableList<ConvenienceSymlink> createOutputDirectoryLinks(
169169
eventHandler.handle(
170170
Event.warn(
171171
String.format(
172-
"cleared convenience symlink(s) %s because their destinations would be ambiguous",
172+
"cleared convenience symlink(s) %s because they wouldn't contain "
173+
+ "requested targets' outputs. Those targets self-transition to multiple "
174+
+ "distinct configurations",
173175
Joiner.on(", ").join(ambiguousLinks))));
174176
}
175177
return convenienceSymlinksBuilder.build();

src/test/java/com/google/devtools/build/lib/buildtool/ConvenienceSymlinkTest.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,8 @@ public void buildingOnlyTargetsWithNullConfigurations_unsetsSymlinks() throws Ex
417417
}
418418

419419
@Test
420-
public void buildingTargetsWithDifferentOutputDirectories_unsetsSymlinks() throws Exception {
420+
public void buildingTargetsWithDifferentOutputDirectories_unsetsSymlinksIfNoneAreTopLevel()
421+
throws Exception {
421422
addOptions("--symlink_prefix=ambiguous-", "--incompatible_skip_genfiles_symlink=false");
422423

423424
Path config = getOutputPath().getRelative("some-imaginary-config");
@@ -431,10 +432,9 @@ public void buildingTargetsWithDifferentOutputDirectories_unsetsSymlinks() throw
431432

432433
write(
433434
"targets/BUILD",
434-
"basic_rule(name='default')",
435435
"incoming_transition_rule(name='config1', path='set_from_config1')",
436436
"incoming_transition_rule(name='config2', path='set_from_config2')");
437-
buildTarget("//targets:default", "//targets:config1", "//targets:config2");
437+
buildTarget("//targets:config1", "//targets:config2");
438438

439439
// there should be nothing at any of the convenience symlinks which depend on configuration -
440440
// the symlinks put there during the simulated prior build should have been deleted
@@ -454,6 +454,49 @@ public void buildingTargetsWithDifferentOutputDirectories_unsetsSymlinks() throw
454454
getOutputPath());
455455
}
456456

457+
@Test
458+
public void buildingTargetsWithDifferentOutputDirectories_setsSymlinksIfAnyAreTopLevel()
459+
throws Exception {
460+
addOptions(
461+
"--symlink_prefix=ambiguous-",
462+
"--incompatible_skip_genfiles_symlink=false",
463+
"--incompatible_merge_genfiles_directory=false",
464+
"--incompatible_skip_genfiles_symlink=false");
465+
466+
Path config = getOutputPath().getRelative("some-imaginary-config");
467+
// put symlinks at the convenience symlinks spots to simulate a prior build
468+
Path binLink = getWorkspace().getChild("ambiguous-bin");
469+
binLink.createSymbolicLink(config.getChild("bin"));
470+
Path genfilesLink = getWorkspace().getChild("ambiguous-genfiles");
471+
genfilesLink.createSymbolicLink(config.getChild("genfiles"));
472+
Path testlogsLink = getWorkspace().getChild("ambiguous-testlogs");
473+
testlogsLink.createSymbolicLink(config.getChild("testlogs"));
474+
475+
write(
476+
"targets/BUILD",
477+
"basic_rule(name='default')",
478+
"incoming_transition_rule(name='config1', path='set_from_config1')");
479+
buildTarget("//targets:default", "//targets:config1");
480+
481+
assertThat(getConvenienceSymlinks())
482+
.containsExactly(
483+
"ambiguous-bin",
484+
getOutputPath()
485+
.getRelative("default-" + getTargetConfiguration().getCpu() + "-fastbuild/bin"),
486+
"ambiguous-genfiles",
487+
getOutputPath()
488+
.getRelative(
489+
"default-" + getTargetConfiguration().getCpu() + "-fastbuild/genfiles"),
490+
"ambiguous-testlogs",
491+
getOutputPath()
492+
.getRelative(
493+
"default-" + getTargetConfiguration().getCpu() + "-fastbuild/testlogs"),
494+
"ambiguous-" + TestConstants.WORKSPACE_NAME,
495+
getExecRoot(),
496+
"ambiguous-out",
497+
getOutputPath());
498+
}
499+
457500
@Test
458501
public void buildingTargetsWithSameConfiguration_setsSymlinks() throws Exception {
459502
addOptions(

0 commit comments

Comments
 (0)