Skip to content

Commit d052ece

Browse files
philsccopybara-github
authored andcommitted
Expand target_compatible_with to all non-workspace rules
This patch makes it so the `target_compatible_with` attribute can be used with all non-workspace rules. The motivation here is to allow rules like `filegroup` and `cc_import` to also make use of incompatible target skipping. Even though these rules don't inherently generate files that are incompatible with the target platform, they can be used to provide incompatible files to other targets. Before this patch the user had to do something like this to create an incompatible pre-compiled library: cc_import( name = "foo_import", shared_library = "foo.so", ) cc_library( name = "foo", deps = [":foo_import"], target_compatible_with = ["//:foo_platform"], ) Now users can directly declare compatibility on the `cc_import` rule. cc_import( name = "foo_import", shared_library = "foo.so", target_compatible_with = ["//:foo_platform"], ) Unfortunately, This does mean that some rules like `cc_toolchain` now have a `target_compatible_with` that doesn't serve any purpose. Before the changes in `BaseRulesClasses.java` the test would error out with meesages like this: //target_skipping:some_precompiled_library: no such attribute 'target_compatible_with' in 'cc_import' rule //target_skipping:filegroup: no such attribute 'target_compatible_with' in 'filegroup' rule I also took this opportunity to update the documentation a bit. Fixes #12745 Closes #13170. PiperOrigin-RevId: 363185186
1 parent ec17683 commit d052ece

File tree

4 files changed

+75
-10
lines changed

4 files changed

+75
-10
lines changed

src/main/java/com/google/devtools/build/docgen/templates/attributes/common/target_compatible_with.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
rule type. If the target platform does not satisfy all listed constraints then
1111
the target is considered <em>incompatible</em>. Incompatible targets are
1212
skipped for building and testing when the target pattern is expanded
13-
(e.g. `//...`, `:all`). When explicitly specified on the command line,
14-
incompatible targets cause Bazel to print an error and cause a build or test
15-
failure.
13+
(e.g. <code>//...</code>, <code>:all</code>). When explicitly specified on the
14+
command line, incompatible targets cause Bazel to print an error and cause a
15+
build or test failure.
1616
</p>
1717

1818
<p>
@@ -25,6 +25,13 @@
2525
with all platforms.
2626
<p>
2727

28+
<p>
29+
All rules other than [Workspace Rules](workspace.html) support this attribute.
30+
For some rules this attribute has no effect. For example, specifying
31+
<code>target_compatible_with</code> for a
32+
<code><a href="c-cpp.html#cc_toolchain">cc_toolchain</a></code> is not useful.
33+
<p>
34+
2835
<p>
2936
See the
3037
<a href="../platforms.html#skipping-incompatible-targets">Platforms</a>

src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,13 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
381381
.add(
382382
attr("distribs", DISTRIBUTIONS)
383383
.nonconfigurable("Used in core loading phase logic with no access to configs"))
384+
// Any rule that has provides its own meaning for the "target_compatible_with" attribute
385+
// has to be excluded in `RuleContextConstraintSemantics.incompatibleConfiguredTarget()`.
386+
.add(
387+
attr(RuleClass.TARGET_RESTRICTED_TO_ATTR, LABEL_LIST)
388+
.mandatoryProviders(ConstraintValueInfo.PROVIDER.id())
389+
// This should be configurable to allow for complex types of restrictions.
390+
.allowedFileTypes(FileTypeSet.NO_FILE))
384391
.build();
385392
}
386393

@@ -441,11 +448,6 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
441448
.allowedFileTypes()
442449
.nonconfigurable("Used in toolchain resolution")
443450
.value(ImmutableList.of()))
444-
.add(
445-
attr(RuleClass.TARGET_RESTRICTED_TO_ATTR, LABEL_LIST)
446-
.mandatoryProviders(ConstraintValueInfo.PROVIDER.id())
447-
// This should be configurable to allow for complex types of restrictions.
448-
.allowedFileTypes(FileTypeSet.NO_FILE))
449451
.build();
450452
}
451453

src/main/java/com/google/devtools/build/lib/analysis/constraints/RuleContextConstraintSemantics.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,8 +907,11 @@ public static ConfiguredTarget incompatibleConfiguredTarget(
907907
RuleContext ruleContext,
908908
OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> prerequisiteMap)
909909
throws ActionConflictException, InterruptedException {
910-
// The target (ruleContext) is incompatible if explicitly specified to be.
911-
if (ruleContext.getRule().getRuleClassObject().useToolchainResolution()
910+
// The target (ruleContext) is incompatible if explicitly specified to be. Any rule that
911+
// provides its own meaning for the "target_compatible_with" attribute has to be excluded here.
912+
// For example, the "toolchain" rule uses "target_compatible_with" for bazel's toolchain
913+
// resolution.
914+
if (!ruleContext.getRule().getRuleClass().equals("toolchain")
912915
&& ruleContext.attributes().has("target_compatible_with")) {
913916
ImmutableList<ConstraintValueInfo> invalidConstraintValues =
914917
PlatformProviderUtils.constraintValues(

src/test/shell/integration/target_compatible_with_test.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,59 @@ EOF
299299
expect_log 'Target //target_skipping:filegroup is incompatible and cannot be built'
300300
}
301301
302+
# Validates that filegroups and other rules that don't inherit from
303+
# `NativeActionCreatingRule` can be marked with target_compatible_with. This is
304+
# a regression test for https://github.com/bazelbuild/bazel/issues/12745.
305+
function test_skipping_for_rules_that_dont_create_actions() {
306+
# Create a fake shared library for cc_import.
307+
echo > target_skipping/some_precompiled_library.so
308+
309+
cat >> target_skipping/BUILD <<EOF
310+
cc_import(
311+
name = "some_precompiled_library",
312+
shared_library = "some_precompiled_library.so",
313+
target_compatible_with = [
314+
":foo3",
315+
],
316+
)
317+
318+
cc_binary(
319+
name = "some_binary",
320+
deps = [
321+
":some_precompiled_library",
322+
],
323+
)
324+
325+
filegroup(
326+
name = "filegroup",
327+
srcs = [
328+
"some_precompiled_library.so",
329+
],
330+
target_compatible_with = [
331+
":foo3",
332+
],
333+
)
334+
EOF
335+
336+
cd target_skipping || fail "couldn't cd into workspace"
337+
338+
bazel build \
339+
--show_result=10 \
340+
--host_platform=@//target_skipping:foo1_bar1_platform \
341+
--platforms=@//target_skipping:foo1_bar1_platform \
342+
:all &> "${TEST_log}" || fail "Bazel failed unexpectedly."
343+
expect_log 'Target //target_skipping:some_precompiled_library was skipped'
344+
expect_log 'Target //target_skipping:some_binary was skipped'
345+
expect_log 'Target //target_skipping:filegroup was skipped'
346+
347+
bazel build \
348+
--show_result=10 \
349+
--host_platform=@//target_skipping:foo1_bar1_platform \
350+
--platforms=@//target_skipping:foo1_bar1_platform \
351+
:filegroup &> "${TEST_log}" && fail "Bazel passed unexpectedly."
352+
expect_log 'Target //target_skipping:filegroup is incompatible and cannot be built'
353+
}
354+
302355
# Validates that incompatible target skipping errors behave nicely with
303356
# --keep_going. In other words, even if there's an error in the target skipping
304357
# (e.g. because the user explicitly requested an incompatible target) we still

0 commit comments

Comments
 (0)