Skip to content

Commit a09cf42

Browse files
committed
cquery: Include toolchains as ruleInputs
These were already returned in a text output for a deps query - this adds them also as ruleInputs.
1 parent 00dfa2e commit a09cf42

File tree

5 files changed

+111
-8
lines changed

5 files changed

+111
-8
lines changed

src/main/java/com/google/devtools/build/lib/query2/cquery/ProtoOutputFormatterCallback.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.google.common.collect.ImmutableList;
1919
import com.google.common.collect.ImmutableMap;
20+
import com.google.common.collect.ImmutableSortedSet;
2021
import com.google.common.collect.Maps;
2122
import com.google.common.collect.Ordering;
2223
import com.google.devtools.build.lib.actions.BuildConfigurationEvent;
@@ -27,6 +28,7 @@
2728
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
2829
import com.google.devtools.build.lib.analysis.config.BuildOptions;
2930
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
31+
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
3032
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
3133
import com.google.devtools.build.lib.cmdline.Label;
3234
import com.google.devtools.build.lib.events.ExtendedEventHandler;
@@ -243,7 +245,20 @@ public void processOutput(Iterable<ConfiguredTarget> partialResult)
243245
// we will want to add relevant tests.
244246
currentTarget = keyedConfiguredTarget;
245247
Target target = accessor.getTarget(keyedConfiguredTarget);
246-
Build.Target.Builder targetBuilder = formatter.toTargetProtoBuffer(target).toBuilder();
248+
249+
// Toolchain dependencies appear as implicit dependencies, but don't appear on any attribute,
250+
// which means they won't get detected by ruleInputs discovery which traverses attributes to get inputs.
251+
// But we know here from our ConfiguredTarget that they are dependencies.
252+
// Artificially provide these implicit dependencies as inputs.
253+
ImmutableSortedSet.Builder<Label> implicitDeps = ImmutableSortedSet.naturalOrder();
254+
if (keyedConfiguredTarget instanceof RuleConfiguredTarget) {
255+
RuleConfiguredTarget ruleConfiguredTarget = (RuleConfiguredTarget) keyedConfiguredTarget;
256+
for (ConfiguredTargetKey implicitDep : ruleConfiguredTarget.getImplicitDeps()) {
257+
implicitDeps.add(implicitDep.getLabel());
258+
}
259+
}
260+
261+
Build.Target.Builder targetBuilder = formatter.toTargetProtoBuffer(target, implicitDeps.build()).toBuilder();
247262
if (target instanceof Rule && !Transitions.NONE.equals(options.transitions)) {
248263
try {
249264
for (CqueryTransitionResolver.ResolvedTransition resolvedTransition :

src/main/java/com/google/devtools/build/lib/query2/query/output/ProtoOutputFormatter.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.google.common.collect.ImmutableMap;
2727
import com.google.common.collect.ImmutableMultimap;
2828
import com.google.common.collect.ImmutableSet;
29+
import com.google.common.collect.ImmutableSortedSet;
2930
import com.google.common.collect.Iterables;
3031
import com.google.common.collect.Maps;
3132
import com.google.common.hash.HashFunction;
@@ -170,12 +171,12 @@ public ThreadSafeOutputFormatterCallback<Target> createStreamCallback(
170171
}
171172

172173
/** Converts a logical {@link Target} object into a {@link Build.Target} protobuffer. */
173-
public Build.Target toTargetProtoBuffer(Target target) throws InterruptedException {
174-
return toTargetProtoBuffer(target, /*extraDataForAttrHash=*/ "");
174+
public Build.Target toTargetProtoBuffer(Target target, ImmutableSortedSet<Label> extraImplicitDeps) throws InterruptedException {
175+
return toTargetProtoBuffer(target, extraImplicitDeps, /*extraDataForAttrHash=*/ "");
175176
}
176177

177178
/** Converts a logical {@link Target} object into a {@link Build.Target} protobuffer. */
178-
public Build.Target toTargetProtoBuffer(Target target, Object extraDataForAttrHash)
179+
private Build.Target toTargetProtoBuffer(Target target, ImmutableSortedSet<Label> extraImplicitDeps, Object extraDataForAttrHash)
179180
throws InterruptedException {
180181
Build.Target.Builder targetPb = Build.Target.newBuilder();
181182

@@ -243,7 +244,11 @@ public Build.Target toTargetProtoBuffer(Target target, Object extraDataForAttrHa
243244
// Include explicit elements for all direct inputs and outputs of a rule; this goes beyond
244245
// what is available from the attributes above, since it may also (depending on options)
245246
// include implicit outputs, exec-configuration outputs, and default values.
246-
rule.getSortedLabels(dependencyFilter)
247+
ImmutableSortedSet<Label> ruleInputs = ImmutableSortedSet.<Label>naturalOrder()
248+
.addAll(rule.getSortedLabels(dependencyFilter))
249+
.addAll(extraImplicitDeps)
250+
.build();
251+
ruleInputs
247252
.forEach(input -> rulePb.addRuleInput(input.toString()));
248253
rule.getOutputFiles().stream()
249254
.distinct()
@@ -565,7 +570,7 @@ public void processOutput(Iterable<Target> partialResult)
565570
// constructing and serializing a QueryResult proto are protected by test coverage and proto
566571
// best practices.
567572
for (Target target : partialResult) {
568-
codedOut.writeMessage(QueryResult.TARGET_FIELD_NUMBER, toTargetProtoBuffer(target));
573+
codedOut.writeMessage(QueryResult.TARGET_FIELD_NUMBER, toTargetProtoBuffer(target, ImmutableSortedSet.of()));
569574
}
570575
}
571576

src/main/java/com/google/devtools/build/lib/query2/query/output/StreamedJSONProtoOutputFormatter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.query2.query.output;
1515

16+
import com.google.common.collect.ImmutableSortedSet;
1617
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
1718
import com.google.devtools.build.lib.packages.Target;
1819
import com.google.devtools.build.lib.query2.engine.OutputFormatterCallback;
@@ -44,7 +45,7 @@ public void processOutput(Iterable<Target> partialResult)
4445
out.write(
4546
jsonPrinter
4647
.omittingInsignificantWhitespace()
47-
.print(toTargetProtoBuffer(target))
48+
.print(toTargetProtoBuffer(target, ImmutableSortedSet.of()))
4849
.getBytes(StandardCharsets.UTF_8));
4950
out.write(System.lineSeparator().getBytes(StandardCharsets.UTF_8));
5051
}

src/main/java/com/google/devtools/build/lib/query2/query/output/StreamedProtoOutputFormatter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.query2.query.output;
1515

16+
import com.google.common.collect.ImmutableSortedSet;
1617
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
1718
import com.google.devtools.build.lib.packages.Target;
1819
import com.google.devtools.build.lib.query2.engine.OutputFormatterCallback;
@@ -38,7 +39,7 @@ public OutputFormatterCallback<Target> createPostFactoStreamCallback(
3839
public void processOutput(Iterable<Target> partialResult)
3940
throws IOException, InterruptedException {
4041
for (Target target : partialResult) {
41-
toTargetProtoBuffer(target).writeDelimitedTo(out);
42+
toTargetProtoBuffer(target, ImmutableSortedSet.of()).writeDelimitedTo(out);
4243
}
4344
}
4445
};

src/test/shell/integration/configured_query_test.sh

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,4 +1521,85 @@ EOF
15211521
assert_contains "$pkg/single_file" output
15221522
}
15231523

1524+
function test_toolchain_rule_inputs() {
1525+
local -r pkg=$FUNCNAME
1526+
mkdir -p $pkg
1527+
1528+
cat >$pkg/BUILD <<EOF
1529+
load("//$pkg:rules.bzl", "my_toolchain", "rule_using_toolchain")
1530+
1531+
toolchain_type(
1532+
name = "toolchain_type",
1533+
visibility = ["//visibility:public"],
1534+
)
1535+
1536+
my_toolchain(
1537+
name = "my_toolchain",
1538+
bin = "echo_hello_to_argv0.sh",
1539+
)
1540+
1541+
toolchain(
1542+
name = "toolchain",
1543+
toolchain = ":my_toolchain",
1544+
toolchain_type = ":toolchain_type",
1545+
)
1546+
1547+
rule_using_toolchain(
1548+
name = "rule",
1549+
)
1550+
EOF
1551+
1552+
cat >$pkg/rules.bzl <<EOF
1553+
def _rule_using_toolchain_impl(ctx):
1554+
output_file = ctx.actions.declare_file("output_file")
1555+
1556+
bin = ctx.toolchains["//$pkg:toolchain_type"].bin
1557+
1558+
args = ctx.actions.args()
1559+
args.add(output_file.path)
1560+
1561+
ctx.actions.run(
1562+
outputs = [output_file],
1563+
executable = bin.path,
1564+
arguments = [output_file.path],
1565+
tools = [bin],
1566+
use_default_shell_env = True,
1567+
)
1568+
1569+
return [
1570+
DefaultInfo(
1571+
files = depset([output_file]),
1572+
),
1573+
]
1574+
1575+
rule_using_toolchain = rule(
1576+
implementation = _rule_using_toolchain_impl,
1577+
toolchains = ["//$pkg:toolchain_type"],
1578+
)
1579+
1580+
def _toolchain_impl(ctx):
1581+
return [
1582+
platform_common.ToolchainInfo(
1583+
bin = ctx.file.bin,
1584+
),
1585+
]
1586+
1587+
my_toolchain = rule(
1588+
implementation = _toolchain_impl,
1589+
attrs = {
1590+
"bin": attr.label(
1591+
allow_single_file = True,
1592+
executable = True,
1593+
cfg = "exec",
1594+
),
1595+
},
1596+
)
1597+
EOF
1598+
touch $pkg/echo_hello_to_argv0.sh
1599+
chmod 0755 $pkg/echo_hello_to_argv0.sh
1600+
1601+
bazel cquery --output=textproto --extra_toolchains=//$pkg:toolchain //$pkg:rule > output 2>"$TEST_log" || fail "Unexpected failure"
1602+
assert_contains "rule_input: \"//$pkg:my_toolchain\"" output
1603+
}
1604+
15241605
run_suite "${PRODUCT_NAME} configured query tests"

0 commit comments

Comments
 (0)