From 0d68da5d5068dab7f68391f35883d78303554306 Mon Sep 17 00:00:00 2001 From: Googler Date: Fri, 23 Feb 2024 14:13:55 -0800 Subject: [PATCH] BEGIN_PUBLIC Implement cc_args_list. It's completely unneccesary to implement it this early, but collecting args lists is also required for cc_feature. END_PUBLIC PiperOrigin-RevId: 609833962 Change-Id: I369a929af4280c0a7ebbe2e13159b640c1968209 --- cc/toolchains/args_list.bzl | 35 ++++++++++ cc/toolchains/impl/collect.bzl | 36 ++++++++++ tests/rule_based_toolchain/args_list/BUILD | 45 +++++++++++++ .../args_list/args_list_test.bzl | 67 +++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 cc/toolchains/args_list.bzl create mode 100644 tests/rule_based_toolchain/args_list/BUILD create mode 100644 tests/rule_based_toolchain/args_list/args_list_test.bzl diff --git a/cc/toolchains/args_list.bzl b/cc/toolchains/args_list.bzl new file mode 100644 index 0000000..fbbaad5 --- /dev/null +++ b/cc/toolchains/args_list.bzl @@ -0,0 +1,35 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""All providers for rule-based bazel toolchain config.""" + +load( + "//cc/toolchains/impl:collect.bzl", + "collect_args_lists", +) +load(":cc_toolchain_info.bzl", "ArgsListInfo") + +def _cc_args_list_impl(ctx): + return [collect_args_lists(ctx.attr.args, ctx.label)] + +cc_args_list = rule( + implementation = _cc_args_list_impl, + doc = "A list of cc_args", + attrs = { + "args": attr.label_list( + providers = [ArgsListInfo], + doc = "The cc_args to include", + ), + }, + provides = [ArgsListInfo], +) diff --git a/cc/toolchains/impl/collect.bzl b/cc/toolchains/impl/collect.bzl index 9d97471..e1c508f 100644 --- a/cc/toolchains/impl/collect.bzl +++ b/cc/toolchains/impl/collect.bzl @@ -16,6 +16,7 @@ load( "//cc/toolchains:cc_toolchain_info.bzl", "ActionTypeSetInfo", + "ArgsListInfo", "ToolInfo", ) @@ -109,3 +110,38 @@ def collect_tools(ctx, targets, fail = fail): fail("Expected %s to be a cc_tool or a binary rule" % target.label) return tools + +def collect_args_lists(targets, label): + """Collects a label_list of ArgsListInfo into a single ArgsListInfo + + Args: + targets: (List[Target]) A label_list of targets providing ArgsListInfo + label: The label to attach to the resulting ArgsListInfo + Returns: + An ArgsListInfo that is the result of joining all of the ArgsListInfos + together. + """ + args = [] + by_action = {} + transitive_files = [] + for target in targets: + args_list = target[ArgsListInfo] + args.extend(args_list.args) + transitive_files.extend([args_info.files for args_info in args_list.args]) + for value in args_list.by_action: + out = by_action.setdefault( + value.action, + struct(args = [], transitive_files = [], action = value.action), + ) + out.args.extend(value.args) + out.transitive_files.append(value.files) + + return ArgsListInfo( + label = label, + args = tuple(args), + files = depset(transitive = transitive_files), + by_action = tuple([ + struct(action = k, args = v.args, files = depset(transitive = v.transitive_files)) + for k, v in by_action.items() + ]), + ) diff --git a/tests/rule_based_toolchain/args_list/BUILD b/tests/rule_based_toolchain/args_list/BUILD new file mode 100644 index 0000000..4120d28 --- /dev/null +++ b/tests/rule_based_toolchain/args_list/BUILD @@ -0,0 +1,45 @@ +load("@rules_testing//lib:util.bzl", "util") +load("//cc/toolchains:args.bzl", "cc_args") +load("//cc/toolchains:args_list.bzl", "cc_args_list") +load("//tests/rule_based_toolchain:analysis_test_suite.bzl", "analysis_test_suite") +load(":args_list_test.bzl", "TARGETS", "TESTS") + +util.helper_target( + cc_args, + name = "c_compile_args", + actions = ["//tests/rule_based_toolchain/actions:c_compile"], + additional_files = ["//tests/rule_based_toolchain/testdata:file1"], + args = ["c"], +) + +util.helper_target( + cc_args, + name = "cpp_compile_args", + actions = ["//tests/rule_based_toolchain/actions:cpp_compile"], + additional_files = ["//tests/rule_based_toolchain/testdata:file2"], + args = ["cpp"], +) + +util.helper_target( + cc_args, + name = "all_compile_args", + actions = ["//tests/rule_based_toolchain/actions:all_compile"], + additional_files = ["//tests/rule_based_toolchain/testdata:multiple1"], + args = ["all"], +) + +util.helper_target( + cc_args_list, + name = "args_list", + args = [ + ":c_compile_args", + ":cpp_compile_args", + ":all_compile_args", + ], +) + +analysis_test_suite( + name = "test_suite", + targets = TARGETS, + tests = TESTS, +) diff --git a/tests/rule_based_toolchain/args_list/args_list_test.bzl b/tests/rule_based_toolchain/args_list/args_list_test.bzl new file mode 100644 index 0000000..1d37145 --- /dev/null +++ b/tests/rule_based_toolchain/args_list/args_list_test.bzl @@ -0,0 +1,67 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for the cc_args rule.""" + +load( + "//cc/toolchains:cc_toolchain_info.bzl", + "ActionTypeInfo", + "ArgsInfo", + "ArgsListInfo", +) + +visibility("private") + +_C_COMPILE_FILE = "tests/rule_based_toolchain/testdata/file1" +_CPP_COMPILE_FILE = "tests/rule_based_toolchain/testdata/file2" +_BOTH_FILE = "tests/rule_based_toolchain/testdata/multiple1" + +def _collect_args_lists_test(env, targets): + args = env.expect.that_target(targets.args_list).provider(ArgsListInfo) + args.args().contains_exactly([ + targets.c_compile_args.label, + targets.cpp_compile_args.label, + targets.all_compile_args.label, + ]) + args.files().contains_exactly([ + _C_COMPILE_FILE, + _CPP_COMPILE_FILE, + _BOTH_FILE, + ]) + + c_compile_action = args.by_action().get(targets.c_compile[ActionTypeInfo]) + cpp_compile_action = args.by_action().get(targets.cpp_compile[ActionTypeInfo]) + + c_compile_action.files().contains_exactly([_C_COMPILE_FILE, _BOTH_FILE]) + c_compile_action.args().contains_exactly([ + targets.c_compile_args[ArgsInfo], + targets.all_compile_args[ArgsInfo], + ]) + cpp_compile_action.files().contains_exactly([_CPP_COMPILE_FILE, _BOTH_FILE]) + cpp_compile_action.args().contains_exactly([ + targets.cpp_compile_args[ArgsInfo], + targets.all_compile_args[ArgsInfo], + ]) + +TARGETS = [ + ":c_compile_args", + ":cpp_compile_args", + ":all_compile_args", + ":args_list", + "//tests/rule_based_toolchain/actions:c_compile", + "//tests/rule_based_toolchain/actions:cpp_compile", +] + +TESTS = { + "collect_args_lists_test": _collect_args_lists_test, +}