Skip to content

Commit

Permalink
Trim input build settings after transition
Browse files Browse the repository at this point in the history
By convention, BuildOptions should not contain Starlark build settings
that are set to their default values. However, if a Starlark transition
has a build setting as an input, the value of that setting has to be
added to the input BuildOptions temporarily so that it can be read by
the transition.

Before this commit, if a build setting was an input but not an output of
a transition, its default value remained in the BuildOptions and could
cause action conflicts. With this commit, all build settings rather than
only output build settings are trimmed post-transition if they are set
to their default value.

Fixes #12888.

Closes #13971.

PiperOrigin-RevId: 399532377
  • Loading branch information
fmeum authored and copybara-github committed Sep 28, 2021
1 parent 2f63e92 commit 5e57e84
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,16 @@ public static Map<String, BuildOptions> validate(
Map<PackageValue.Key, PackageValue> buildSettingPackages,
Map<String, BuildOptions> toOptions)
throws TransitionException {
// collect settings changed during this transition and their types
// Collect settings changed during this transition and their types. This includes settings that
// were only used as inputs as to the transition and thus had their default values added to the
// fromOptions, which in case of a no-op transition directly end up in toOptions.
Map<Label, Rule> changedSettingToRule = Maps.newHashMap();
root.visit(
(StarlarkTransitionVisitor)
transition -> {
ImmutableSet<Label> changedSettings =
getRelevantStarlarkSettingsFromTransition(transition, Settings.OUTPUTS);
getRelevantStarlarkSettingsFromTransition(
transition, Settings.INPUTS_AND_OUTPUTS);
for (Label setting : changedSettings) {
changedSettingToRule.put(
setting, getActual(buildSettingPackages, setting).getAssociatedRule());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2249,4 +2249,165 @@ public void testNoPlatformChange() throws Exception {
assertThat(getConfiguration(dep).getOptions().get(PlatformOptions.class).platforms)
.containsExactly(Label.parseAbsoluteUnchecked("//platforms:my_platform"));
}

@Test
public void testEffectiveNoopTransitionTrimsInputBuildSettings() throws Exception {
writeAllowlistFile();
scratch.file(
"test/starlark/rules.bzl",
"def _string_impl(ctx):",
" return []",
"string_flag = rule(",
" implementation = _string_impl,",
" build_setting = config.string(flag = True),",
")",
"def _no_op_transition_impl(settings, attr):",
" return {",
" '//test/starlark:input_and_output': settings['//test/starlark:input_and_output'],",
" '//test/starlark:output_only': 'output_only_default',",
" }",
"_no_op_transition = transition(",
" implementation = _no_op_transition_impl,",
" inputs = [",
" '//test/starlark:input_only',",
" '//test/starlark:input_and_output',",
" ],",
" outputs = [",
" '//test/starlark:input_and_output',",
" '//test/starlark:output_only',",
" ],",
")",
"def _apply_transition_impl(ctx):",
" ctx.actions.symlink(",
" output = ctx.outputs.out,",
" target_file = ctx.file.target,",
" )",
" return [DefaultInfo(executable = ctx.outputs.out)]",
"apply_transition = rule(",
" implementation = _apply_transition_impl,",
" attrs = {",
" 'target': attr.label(",
" cfg = _no_op_transition,",
" allow_single_file = True,",
" ),",
" 'out': attr.output(),",
" '_allowlist_function_transition': attr.label(",
" default = '//tools/allowlists/function_transition_allowlist',",
" ),",
" },",
" executable = False,",
")");
scratch.file(
"test/starlark/BUILD",
"load('//test/starlark:rules.bzl', 'apply_transition', 'string_flag')",
"",
"string_flag(",
" name = 'input_only',",
" build_setting_default = 'input_only_default',",
")",
"string_flag(",
" name = 'input_and_output',",
" build_setting_default = 'input_and_output_default',",
")",
"string_flag(",
" name = 'output_only',",
" build_setting_default = 'output_only_default',",
")",
"cc_binary(",
" name = 'main',",
" srcs = ['main.cc'],",
")",
"apply_transition(",
" name = 'transitioned_main',",
" target = ':main',",
" out = 'main_out',",
")");

update(
ImmutableList.of("//test/starlark:main", "//test/starlark:transitioned_main"),
/*keepGoing=*/ false,
LOADING_PHASE_THREADS,
/*doAnalysis=*/ true,
new EventBus());
assertNoEvents();
}

@Test
public void testExplicitNoopTransitionTrimsInputBuildSettings() throws Exception {
writeAllowlistFile();
scratch.file(
"test/starlark/rules.bzl",
"def _string_impl(ctx):",
" return []",
"string_flag = rule(",
" implementation = _string_impl,",
" build_setting = config.string(flag = True),",
")",
"def _no_op_transition_impl(settings, attr):",
" return {}",
"_no_op_transition = transition(",
" implementation = _no_op_transition_impl,",
" inputs = [",
" '//test/starlark:input_only',",
" '//test/starlark:input_and_output',",
" ],",
" outputs = [",
" '//test/starlark:input_and_output',",
" '//test/starlark:output_only',",
" ],",
")",
"def _apply_transition_impl(ctx):",
" ctx.actions.symlink(",
" output = ctx.outputs.out,",
" target_file = ctx.file.target,",
" )",
" return [DefaultInfo(executable = ctx.outputs.out)]",
"apply_transition = rule(",
" implementation = _apply_transition_impl,",
" attrs = {",
" 'target': attr.label(",
" cfg = _no_op_transition,",
" allow_single_file = True,",
" ),",
" 'out': attr.output(),",
" '_allowlist_function_transition': attr.label(",
" default = '//tools/allowlists/function_transition_allowlist',",
" ),",
" },",
" executable = False,",
")");
scratch.file(
"test/starlark/BUILD",
"load('//test/starlark:rules.bzl', 'apply_transition', 'string_flag')",
"",
"string_flag(",
" name = 'input_only',",
" build_setting_default = 'input_only_default',",
")",
"string_flag(",
" name = 'input_and_output',",
" build_setting_default = 'input_and_output_default',",
")",
"string_flag(",
" name = 'output_only',",
" build_setting_default = 'output_only_default',",
")",
"cc_binary(",
" name = 'main',",
" srcs = ['main.cc'],",
")",
"apply_transition(",
" name = 'transitioned_main',",
" target = ':main',",
" out = 'main_out',",
")");

update(
ImmutableList.of("//test/starlark:main", "//test/starlark:transitioned_main"),
/*keepGoing=*/ false,
LOADING_PHASE_THREADS,
/*doAnalysis=*/ true,
new EventBus());
assertNoEvents();
}
}

0 comments on commit 5e57e84

Please sign in to comment.