Skip to content

Commit

Permalink
Add --skip_incompatible_explicit_targets option
Browse files Browse the repository at this point in the history
This adds an argument to skip incompatible targets even if they were
explicitly requested on the command line. This is useful for CI to
allow it to build changed targets from rdeps queries without needing
to filter them all through a cquery to check if they are compatible.

Closes bazelbuild#17403

RELNOTES: Add `--skip_incompatible_explicit_targets` option
  • Loading branch information
marczych-zoox committed Feb 3, 2023
1 parent 93777cc commit 792a7e7
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 9 deletions.
3 changes: 2 additions & 1 deletion site/en/extending/platforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ In other words, `test_suite` targets on the command line behave like `:all` and
`test_suite` targets with incompatible tests to also be incompatible.

Explicitly specifying an incompatible target on the command line results in an
error message and a failed build.
error message and a failed build unless `--skip_incompatible_explicit_targets`
is enabled:

```console
$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ public AnalysisResult update(
ImmutableMap<String, String> aspectsParameters,
AnalysisOptions viewOptions,
boolean keepGoing,
boolean skipIncompatibleExplicitTargets,
boolean checkForActionConflicts,
QuiescingExecutors executors,
TopLevelArtifactContext topLevelOptions,
Expand Down Expand Up @@ -489,7 +490,11 @@ public AnalysisResult update(

PlatformRestrictionsResult platformRestrictions =
topLevelConstraintSemantics.checkPlatformRestrictions(
skyframeAnalysisResult.getConfiguredTargets(), explicitTargetPatterns, keepGoing);
skyframeAnalysisResult.getConfiguredTargets(),
explicitTargetPatterns,
keepGoing,
skipIncompatibleExplicitTargets
);

if (!platformRestrictions.targetsWithErrors().isEmpty()) {
// If there are any errored targets (e.g. incompatible targets that are explicitly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ public static PlatformCompatibility compatibilityWithPlatformRestrictions(
ConfiguredTarget configuredTarget,
ExtendedEventHandler eventHandler,
boolean eagerlyThrowError,
boolean explicitlyRequested)
boolean explicitlyRequested,
boolean skipIncompatibleExplicitTargets)
throws TargetCompatibilityCheckException {

RuleContextConstraintSemantics.IncompatibleCheckResult incompatibleCheckResult =
Expand All @@ -124,7 +125,7 @@ public static PlatformCompatibility compatibilityWithPlatformRestrictions(
// We need the label in unambiguous form here. I.e. with the "@" prefix for targets in the
// main repository. explicitTargetPatterns is also already in the unambiguous form to make
// comparison succeed regardless of the provided form.
if (explicitlyRequested) {
if (!skipIncompatibleExplicitTargets && explicitlyRequested) {
if (eagerlyThrowError) {
// Use the slightly simpler form for printing error messages. I.e. no "@" prefix for
// targets in the main repository.
Expand All @@ -136,7 +137,8 @@ public static PlatformCompatibility compatibilityWithPlatformRestrictions(
String.format(TARGET_INCOMPATIBLE_ERROR_TEMPLATE, configuredTarget.getLabel(), "")));
return PlatformCompatibility.INCOMPATIBLE_EXPLICIT;
}
// If this is not an explicitly requested target we can safely skip it.
// We can safely skip this target if it wasn't explicitly requested or we've been instructed
// to skip explicitly requested targets.
return PlatformCompatibility.INCOMPATIBLE_IMPLICIT;
}

Expand Down Expand Up @@ -240,8 +242,8 @@ public static EnvironmentCompatibility compatibilityWithTargetEnvironment(
* the command line should be skipped.
*
* <p>Targets that are incompatible with the target platform and *are* explicitly requested on the
* command line are errored. Having one or more errored targets will cause the entire build to
* fail with an error message.
* command line are errored unless --skip_incompatible_explicit_targets is enabled. Having one or
* more errored targets will cause the entire build to fail with an error message.
*
* @param topLevelTargets the build's top-level targets
* @param explicitTargetPatterns the set of explicit target patterns specified by the user on the
Expand All @@ -254,7 +256,8 @@ public static EnvironmentCompatibility compatibilityWithTargetEnvironment(
public PlatformRestrictionsResult checkPlatformRestrictions(
ImmutableSet<ConfiguredTarget> topLevelTargets,
ImmutableSet<Label> explicitTargetPatterns,
boolean keepGoing)
boolean keepGoing,
boolean skipIncompatibleExplicitTargets)
throws ViewCreationFailedException {
ImmutableSet.Builder<ConfiguredTarget> incompatibleTargets = ImmutableSet.builder();
ImmutableSet.Builder<ConfiguredTarget> incompatibleButRequestedTargets = ImmutableSet.builder();
Expand All @@ -266,7 +269,8 @@ public PlatformRestrictionsResult checkPlatformRestrictions(
target,
eventHandler,
/*eagerlyThrowError=*/ !keepGoing,
explicitTargetPatterns.contains(target.getLabel()));
explicitTargetPatterns.contains(target.getLabel()),
skipIncompatibleExplicitTargets);
if (PlatformCompatibility.INCOMPATIBLE_EXPLICIT.equals(platformCompatibility)) {
incompatibleButRequestedTargets.add(target);
} else if (PlatformCompatibility.INCOMPATIBLE_IMPLICIT.equals(platformCompatibility)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ private static AnalysisResult runAnalysisPhase(
request.getAspectsParameters(),
request.getViewOptions(),
request.getKeepGoing(),
request.getBuildOptions().skipIncompatibleExplicitTargets,
request.getCheckForActionConflicts(),
env.getQuiescingExecutors(),
request.getTopLevelArtifactContext(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,15 @@ public ThreadConverter() {
@Nullable
public PathFragment aqueryDumpAfterBuildOutputFile;

@Option(
name = "skip_incompatible_explicit_targets",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
help = "Skip incompatible targets that are explicitly listed on the command line."
)
public boolean skipIncompatibleExplicitTargets;

/**
* --nobuild means no execution will be carried out, hence it doesn't make sense to interleave
* analysis and execution in that case and --experimental_merged_skyframe_analysis_execution
Expand Down
28 changes: 28 additions & 0 deletions src/test/shell/integration/target_compatible_with_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,34 @@ function test_failure_on_incompatible_top_level_target() {
expect_log '^ERROR: Build did NOT complete successfully'
}

# Validates that incompatible target skipping works with top level targets when
# --skip_incompatible_explicit_targets is enabled.
function test_success_on_incompatible_top_level_target_with_skipping() {
cd target_skipping || fail "couldn't cd into workspace"

# Validate a variety of ways to refer to the same target.
local -r -a incompatible_targets=(
:pass_on_foo1_bar2
//target_skipping:pass_on_foo1_bar2
@//target_skipping:pass_on_foo1_bar2
)

for incompatible_target in "${incompatible_targets[@]}"; do
echo "Testing ${incompatible_target}"

bazel test \
--show_result=10 \
--host_platform=@//target_skipping:foo1_bar1_platform \
--platforms=@//target_skipping:foo1_bar1_platform \
--build_event_text_file="${TEST_log}".build.json \
--skip_incompatible_explicit_targets \
"${incompatible_target}" &> "${TEST_log}" \
|| fail "Bazel failed unexpectedly."

expect_log '^//target_skipping:pass_on_foo1_bar2 * SKIPPED$'
done
}

# Crudely validates that the build event protocol contains useful information
# when targets are skipped due to incompatibilities.
function test_build_event_protocol() {
Expand Down

0 comments on commit 792a7e7

Please sign in to comment.