mirror of https://github.com/bazelbuild/rules_cc
BEGIN_PUBLIC
Implement cc_args. Also change cc_flag_set / cc_flag_group to cc_args / cc_arg_group. This is to lean into the idea that this is roughly equivalent to ctx.actions.args() END_PUBLIC PiperOrigin-RevId: 608804069 Change-Id: I74ea883b14219f904aaafc4eab902b96a1fb3e3d
This commit is contained in:
parent
2e780ceda9
commit
35fe45e91b
|
@ -36,7 +36,7 @@ sh_binary(
|
||||||
An action config is a mapping from action to:
|
An action config is a mapping from action to:
|
||||||
|
|
||||||
* A list of tools, (the first one matching the execution requirements is used).
|
* A list of tools, (the first one matching the execution requirements is used).
|
||||||
* A list of flags and features that are always enabled for the action
|
* A list of args and features that are always enabled for the action
|
||||||
* A set of additional files required for the action
|
* A set of additional files required for the action
|
||||||
|
|
||||||
Each action can only be specified once in the toolchain. Specifying multiple
|
Each action can only be specified once in the toolchain. Specifying multiple
|
||||||
|
@ -62,7 +62,7 @@ cc_action_config(
|
||||||
name = "c_compile",
|
name = "c_compile",
|
||||||
actions = ["@rules_cc//actions:all_c_compile"],
|
actions = ["@rules_cc//actions:all_c_compile"],
|
||||||
tools = ["@sysroot//:clang"],
|
tools = ["@sysroot//:clang"],
|
||||||
flag_sets = [":my_flag_set"],
|
args = [":my_args"],
|
||||||
implies = [":my_feature"],
|
implies = [":my_feature"],
|
||||||
additional_files = ["@sysroot//:all_header_files"],
|
additional_files = ["@sysroot//:all_header_files"],
|
||||||
)
|
)
|
||||||
|
@ -74,57 +74,109 @@ cc_additional_files_for_actions(
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 3: Define some flag sets
|
## Step 3: Define some arguments
|
||||||
Flag sets are just sets of flags to be associated with actions. Most flag sets
|
Arguments are our replacement for `flag_set` and `env_set`. To add arguments to
|
||||||
are simple, so we provide the shorthand `flags`. However, sometimes you
|
our tools, we take heavy inspiration from bazel's
|
||||||
need to do more complex things, for which we support `flag_groups` instead.
|
[`Args`](https://bazel.build/rules/lib/builtins/Args) type. We provide the same
|
||||||
|
API, with the following caveats:
|
||||||
Flag groups work exactly the same as the existing toolchain definition.
|
* `actions` specifies which actions the arguments apply to (same as `flag_set`).
|
||||||
|
* `requires_any_of` is equivalent to `with_features` on the `flag_set`.
|
||||||
Flag sets are a combination of both `flag_set` and `env_set` from the existing
|
* `args` may be used instead of `add` if your command-line is only strings.
|
||||||
toolchain definition.
|
* `env` may be used to add environment variables to the arguments. Environment
|
||||||
|
variables set by later args take priority.
|
||||||
`cc_flag_set_list` is simply a list of flag sets. This can be used to group
|
* By default, all inputs are automatically added to the corresponding actions.
|
||||||
flag sets together, and preserves ordering.
|
`additional_files` specifies files that are required for an action when using
|
||||||
|
that argument.
|
||||||
|
|
||||||
```
|
```
|
||||||
cc_flag_set(
|
cc_args(
|
||||||
name = "simple",
|
name = "inline",
|
||||||
actions = ["@rules_cc//actions:all_cpp_compile_actions"],
|
actions = ["@rules_cc//actions:all_cpp_compile_actions"],
|
||||||
flags = ["--foo"],
|
args = ["--foo"],
|
||||||
envs = {"FOO": "bar"},
|
requires_any_of = [":feature"]
|
||||||
|
env = {"FOO": "bar"},
|
||||||
|
additional_files = [":file"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
For more complex use cases, we use the same API as `Args`. Values are either:
|
||||||
|
* A list of files (or a single file for `cc_add_args`).
|
||||||
|
* Something returning `CcVariableInfo`, which is equivalent to a list of strings.
|
||||||
|
|
||||||
|
```
|
||||||
|
cc_variable(
|
||||||
|
name = "bar_baz",
|
||||||
|
values = ["bar", "baz"],
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_flag_group(
|
# Expands to CcVariableInfo(values = ["x86_64-unknown-linux-gnu"])
|
||||||
name = "complex_flag_group",
|
custom_variable_rule(
|
||||||
# API TBD
|
name = "triple",
|
||||||
|
...
|
||||||
)
|
)
|
||||||
cc_flag_set(
|
|
||||||
|
# Taken from https://bazel.build/rules/lib/builtins/Args#add
|
||||||
|
cc_add_args(
|
||||||
|
name = "single",
|
||||||
|
arg_name = "--platform",
|
||||||
|
value = ":triple", # Either a single file or a cc_variable
|
||||||
|
format = "%s",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Taken from https://bazel.build/rules/lib/builtins/Args#add_all
|
||||||
|
cc_add_args_all(
|
||||||
|
name = "multiple",
|
||||||
|
arg_name = "--foo",
|
||||||
|
values = [":file", ":file_set"], # Either files or cc_variable.
|
||||||
|
# map_each not supported. Write a custom rule if you want that.
|
||||||
|
format_each = "%s",
|
||||||
|
before_each = "--foo",
|
||||||
|
omit_if_empty = True,
|
||||||
|
uniquify = False,
|
||||||
|
# Expand_directories not yet supported.
|
||||||
|
terminate_with = "foo",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Taken from https://bazel.build/rules/lib/builtins/Args#add_joined
|
||||||
|
cc_add_args_joined(
|
||||||
|
name = "joined",
|
||||||
|
arg_name = "--foo",
|
||||||
|
values = [":file", ":file_set"], # Either files or cc_variable.
|
||||||
|
join_with = ",",
|
||||||
|
# map_each not supported. Write a custom rule if you want that.
|
||||||
|
format_each = "%s",
|
||||||
|
format_joined = "--foo=%s",
|
||||||
|
omit_if_empty = True,
|
||||||
|
uniquify = False,
|
||||||
|
# Expand_directories not yet supported.
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_args(
|
||||||
name = "complex",
|
name = "complex",
|
||||||
actions = ["@rules_cc//actions:c_compile"],
|
actions = ["@rules_cc//actions:c_compile"],
|
||||||
flag_groups = [":complex_flag_group"],
|
add = [":single", ":multiple", ":joined"],
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_flag_set_list(
|
cc_args_list(
|
||||||
name = "all_flags",
|
name = "all_flags",
|
||||||
flag_sets = [":simple", ":complex"],
|
args = [":inline", ":complex"],
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 4: Define some features
|
## Step 4: Define some features
|
||||||
A feature is a set of flags and configurations that can be enabled or disabled.
|
A feature is a set of args and configurations that can be enabled or disabled.
|
||||||
|
|
||||||
Although the existing toolchain recommends using features to avoid duplication
|
Although the existing toolchain recommends using features to avoid duplication
|
||||||
of definitions, we recommend avoiding using features unless you want the user to
|
of definitions, we recommend avoiding using features unless you want the user to
|
||||||
be able to enable / disable the feature themselves. This is because we provide
|
be able to enable / disable the feature themselves. This is because we provide
|
||||||
alternatives such as `cc_flag_set_list` to allow combining flag sets and
|
alternatives such as `cc_args_list` to allow combining arguments and
|
||||||
specifying them on each action in the action config.
|
specifying them on each action in the action config.
|
||||||
|
|
||||||
```
|
```
|
||||||
cc_feature(
|
cc_feature(
|
||||||
name = "my_feature",
|
name = "my_feature",
|
||||||
feature_name = "my_feature",
|
feature_name = "my_feature",
|
||||||
flag_sets = [":all_flags"],
|
args = [":all_args"],
|
||||||
implies = [":other_feature"],
|
implies = [":other_feature"],
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
@ -143,7 +195,7 @@ The `cc_toolchain` macro:
|
||||||
cc_toolchain(
|
cc_toolchain(
|
||||||
name = "toolchain",
|
name = "toolchain",
|
||||||
features = [":my_feature"]
|
features = [":my_feature"]
|
||||||
unconditional_flag_sets = [":all_warnings"],
|
unconditional_args = [":all_warnings"],
|
||||||
action_configs = [":c_compile"],
|
action_configs = [":c_compile"],
|
||||||
additional_files = [":all_action_files"],
|
additional_files = [":all_action_files"],
|
||||||
)
|
)
|
||||||
|
@ -187,7 +239,7 @@ def cc_legacy_features(name, features):
|
||||||
|
|
||||||
|
|
||||||
# Build file
|
# Build file
|
||||||
FOO = feature(name = "foo", flag_sets=[flag_group(...)])
|
FOO = feature(name = "foo", args=[arg_group(...)])
|
||||||
FEATURES = [FOO]
|
FEATURES = [FOO]
|
||||||
cc_legacy_features(name = "legacy_features", features = FEATURES)
|
cc_legacy_features(name = "legacy_features", features = FEATURES)
|
||||||
|
|
||||||
|
@ -240,7 +292,7 @@ Feature requirements can come in two formats.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
* Features can require some subset of features to be enabled.
|
* Features can require some subset of features to be enabled.
|
||||||
* Flag sets can require some subset of features to be enabled, but others to be
|
* Arguments can require some subset of features to be enabled, but others to be
|
||||||
disabled.
|
disabled.
|
||||||
|
|
||||||
This is very confusing for toolchain authors, so we will simplify things with
|
This is very confusing for toolchain authors, so we will simplify things with
|
||||||
|
@ -265,7 +317,7 @@ cc_feature_constraint(
|
||||||
none_of = [":my_other_feature"],
|
none_of = [":my_other_feature"],
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_flag_set(
|
cc_args(
|
||||||
name = "foo",
|
name = "foo",
|
||||||
# All of these provide with_feature.
|
# All of these provide with_feature.
|
||||||
requires_any_of = [":my_feature", ":my_feature_set", ":my_feature_constraint"]
|
requires_any_of = [":my_feature", ":my_feature_set", ":my_feature_constraint"]
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Rules to turn action types into bazel labels."""
|
"""Rules to turn action types into bazel labels."""
|
||||||
|
|
||||||
|
load("//cc/toolchains/impl:collect.bzl", "collect_action_types")
|
||||||
load(":cc_toolchain_info.bzl", "ActionTypeInfo", "ActionTypeSetInfo")
|
load(":cc_toolchain_info.bzl", "ActionTypeInfo", "ActionTypeSetInfo")
|
||||||
|
|
||||||
visibility("public")
|
visibility("public")
|
||||||
|
@ -51,10 +52,7 @@ cc_action_type(
|
||||||
def _cc_action_type_set_impl(ctx):
|
def _cc_action_type_set_impl(ctx):
|
||||||
return [ActionTypeSetInfo(
|
return [ActionTypeSetInfo(
|
||||||
label = ctx.label,
|
label = ctx.label,
|
||||||
actions = depset(transitive = [
|
actions = collect_action_types(ctx.attr.actions),
|
||||||
attr[ActionTypeSetInfo].actions
|
|
||||||
for attr in ctx.attr.actions
|
|
||||||
]),
|
|
||||||
)]
|
)]
|
||||||
|
|
||||||
cc_action_type_set = rule(
|
cc_action_type_set = rule(
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
# 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_action_types",
|
||||||
|
"collect_files",
|
||||||
|
"collect_provider",
|
||||||
|
)
|
||||||
|
load(
|
||||||
|
":cc_toolchain_info.bzl",
|
||||||
|
"ActionTypeSetInfo",
|
||||||
|
"AddArgsInfo",
|
||||||
|
"ArgsInfo",
|
||||||
|
"ArgsListInfo",
|
||||||
|
"FeatureConstraintInfo",
|
||||||
|
)
|
||||||
|
|
||||||
|
visibility("public")
|
||||||
|
|
||||||
|
def _cc_args_impl(ctx):
|
||||||
|
add_args = [AddArgsInfo(
|
||||||
|
label = ctx.label,
|
||||||
|
args = tuple(ctx.attr.args),
|
||||||
|
files = depset([]),
|
||||||
|
)]
|
||||||
|
|
||||||
|
actions = collect_action_types(ctx.attr.actions)
|
||||||
|
files = collect_files(ctx.attr.additional_files)
|
||||||
|
requires = collect_provider(ctx.attr.requires_any_of, FeatureConstraintInfo)
|
||||||
|
|
||||||
|
args = ArgsInfo(
|
||||||
|
label = ctx.label,
|
||||||
|
actions = actions,
|
||||||
|
requires_any_of = tuple(requires),
|
||||||
|
files = files,
|
||||||
|
args = add_args,
|
||||||
|
env = ctx.attr.env,
|
||||||
|
)
|
||||||
|
return [
|
||||||
|
args,
|
||||||
|
ArgsListInfo(label = ctx.label, args = tuple([args])),
|
||||||
|
]
|
||||||
|
|
||||||
|
cc_args = rule(
|
||||||
|
implementation = _cc_args_impl,
|
||||||
|
attrs = {
|
||||||
|
"actions": attr.label_list(
|
||||||
|
providers = [ActionTypeSetInfo],
|
||||||
|
mandatory = True,
|
||||||
|
doc = """A list of action types that this flag set applies to.
|
||||||
|
|
||||||
|
See @rules_cc//cc/toolchains/actions:all for valid options.
|
||||||
|
""",
|
||||||
|
),
|
||||||
|
"additional_files": attr.label_list(
|
||||||
|
allow_files = True,
|
||||||
|
doc = """Files required to add this argument to the command-line.
|
||||||
|
|
||||||
|
For example, a flag that sets the header directory might add the headers in that
|
||||||
|
directory as additional files.
|
||||||
|
""",
|
||||||
|
),
|
||||||
|
"args": attr.string_list(
|
||||||
|
doc = """Arguments that should be added to the command-line.
|
||||||
|
|
||||||
|
These are evaluated in order, with earlier args appearing earlier in the
|
||||||
|
invocation of the underlying tool.
|
||||||
|
""",
|
||||||
|
),
|
||||||
|
"env": attr.string_dict(
|
||||||
|
doc = "Environment variables to be added to the command-line.",
|
||||||
|
),
|
||||||
|
"requires_any_of": attr.label_list(
|
||||||
|
providers = [FeatureConstraintInfo],
|
||||||
|
doc = """This will be enabled when any of the constraints are met.
|
||||||
|
|
||||||
|
If omitted, this flag set will be enabled unconditionally.
|
||||||
|
""",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
provides = [ArgsInfo],
|
||||||
|
doc = """Declares a list of arguments bound to a set of actions.
|
||||||
|
|
||||||
|
Roughly equivalent to ctx.actions.args()
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
cc_args(
|
||||||
|
name = "warnings_as_errors",
|
||||||
|
args = ["-Werror"],
|
||||||
|
)
|
||||||
|
""",
|
||||||
|
)
|
|
@ -19,7 +19,7 @@
|
||||||
# decide to just require users to use the public user-facing rules.
|
# decide to just require users to use the public user-facing rules.
|
||||||
visibility([
|
visibility([
|
||||||
"//cc/toolchains/...",
|
"//cc/toolchains/...",
|
||||||
"//tests/...",
|
"//tests/rule_based_toolchain/...",
|
||||||
])
|
])
|
||||||
|
|
||||||
# Note that throughout this file, we never use a list. This is because mutable
|
# Note that throughout this file, we never use a list. This is because mutable
|
||||||
|
@ -29,6 +29,7 @@ visibility([
|
||||||
|
|
||||||
ActionTypeInfo = provider(
|
ActionTypeInfo = provider(
|
||||||
doc = "A type of action (eg. c-compile, c++-link-executable)",
|
doc = "A type of action (eg. c-compile, c++-link-executable)",
|
||||||
|
# @unsorted-dict-items
|
||||||
fields = {
|
fields = {
|
||||||
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
||||||
"name": "(str) The action name, as defined by action_names.bzl",
|
"name": "(str) The action name, as defined by action_names.bzl",
|
||||||
|
@ -44,23 +45,34 @@ ActionTypeSetInfo = provider(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
FlagGroupInfo = provider(
|
AddArgsInfo = provider(
|
||||||
doc = "A group of flags",
|
doc = "A provider representation of Args.add/add_all/add_joined parameters",
|
||||||
# @unsorted-dict-items
|
# @unsorted-dict-items
|
||||||
fields = {
|
fields = {
|
||||||
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
||||||
"flags": "(Sequence[str]) A list of flags to add to the command-line",
|
"args": "(Sequence[str]) The command-line arguments to add",
|
||||||
|
"files": "(depset[File]) The files required to use this variable",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
FlagSetInfo = provider(
|
ArgsInfo = provider(
|
||||||
doc = "A set of flags to be expanded in the command line for specific actions",
|
doc = "A set of arguments to be added to the command line for specific actions",
|
||||||
# @unsorted-dict-items
|
# @unsorted-dict-items
|
||||||
fields = {
|
fields = {
|
||||||
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
||||||
"actions": "(depset[ActionTypeInfo]) The set of actions this is associated with",
|
"actions": "(depset[ActionTypeInfo]) The set of actions this is associated with",
|
||||||
"requires_any_of": "(Sequence[FeatureConstraintInfo]) This will be enabled if any of the listed predicates are met. Equivalent to with_features",
|
"requires_any_of": "(Sequence[FeatureConstraintInfo]) This will be enabled if any of the listed predicates are met. Equivalent to with_features",
|
||||||
"flag_groups": "(Sequence[FlagGroupInfo]) Set of flag groups to include.",
|
"args": "(Sequence[AddArgsInfo]) The command-line arguments to add.",
|
||||||
|
"files": "(depset[File]) Files required for the args",
|
||||||
|
"env": "(dict[str, str]) Environment variables to apply",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ArgsListInfo = provider(
|
||||||
|
doc = "A ordered list of arguments",
|
||||||
|
# @unsorted-dict-items
|
||||||
|
fields = {
|
||||||
|
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
||||||
|
"args": "(Sequence[ArgsInfo]) The flag sets contained within",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -71,7 +83,7 @@ FeatureInfo = provider(
|
||||||
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
||||||
"name": "(str) The name of the feature",
|
"name": "(str) The name of the feature",
|
||||||
"enabled": "(bool) Whether this feature is enabled by default",
|
"enabled": "(bool) Whether this feature is enabled by default",
|
||||||
"flag_sets": "(depset[FlagSetInfo]) Flag sets enabled by this feature",
|
"args": "(Sequence[ArgsInfo]) Flag sets enabled by this feature",
|
||||||
"implies": "(depset[FeatureInfo]) Set of features implied by this feature",
|
"implies": "(depset[FeatureInfo]) Set of features implied by this feature",
|
||||||
"requires_any_of": "(Sequence[FeatureSetInfo]) A list of feature sets, at least one of which is required to enable this feature. This is semantically equivalent to the requires attribute of rules_cc's FeatureInfo",
|
"requires_any_of": "(Sequence[FeatureSetInfo]) A list of feature sets, at least one of which is required to enable this feature. This is semantically equivalent to the requires attribute of rules_cc's FeatureInfo",
|
||||||
"provides": "(Sequence[MutuallyExclusiveCategoryInfo]) Indicates that this feature is one of several mutually exclusive alternate features.",
|
"provides": "(Sequence[MutuallyExclusiveCategoryInfo]) Indicates that this feature is one of several mutually exclusive alternate features.",
|
||||||
|
@ -100,6 +112,7 @@ FeatureConstraintInfo = provider(
|
||||||
|
|
||||||
MutuallyExclusiveCategoryInfo = provider(
|
MutuallyExclusiveCategoryInfo = provider(
|
||||||
doc = "Multiple features with the category will be mutally exclusive",
|
doc = "Multiple features with the category will be mutally exclusive",
|
||||||
|
# @unsorted-dict-items
|
||||||
fields = {
|
fields = {
|
||||||
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
"label": "(Label) The label defining this provider. Place in error messages to simplify debugging",
|
||||||
"name": "(str) The name of the category",
|
"name": "(str) The name of the category",
|
||||||
|
@ -126,7 +139,7 @@ ActionConfigInfo = provider(
|
||||||
"action": "(ActionTypeInfo) The name of the action",
|
"action": "(ActionTypeInfo) The name of the action",
|
||||||
"enabled": "(bool) If True, this action is enabled unless a rule type explicitly marks it as unsupported",
|
"enabled": "(bool) If True, this action is enabled unless a rule type explicitly marks it as unsupported",
|
||||||
"tools": "(Sequence[ToolInfo]) The tool applied to the action will be the first tool in the sequence with a feature set that matches the feature configuration",
|
"tools": "(Sequence[ToolInfo]) The tool applied to the action will be the first tool in the sequence with a feature set that matches the feature configuration",
|
||||||
"flag_sets": "(Sequence[FlagSetInfo]) Set of flag sets the action sets",
|
"args": "(Sequence[ArgsInfo]) Set of flag sets the action sets",
|
||||||
"implies": "(depset[FeatureInfo]) Set of features implied by this action config",
|
"implies": "(depset[FeatureInfo]) Set of features implied by this action config",
|
||||||
"files": "(depset[File]) The files required to run these actions",
|
"files": "(depset[File]) The files required to run these actions",
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# This directory contains implementations of starlark functions that contain
|
||||||
|
# complex logic. The objective is to keep the rules themselves as simple as
|
||||||
|
# possible, so that we can perform very thorough testing on the implementation.
|
||||||
|
|
||||||
|
# I wanted to call it private / internal, but then buildifier complains about
|
||||||
|
# referencing it from the tests directory.
|
|
@ -0,0 +1,55 @@
|
||||||
|
# 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.
|
||||||
|
"""Helper functions to allow us to collect data from attr.label_list."""
|
||||||
|
|
||||||
|
load(
|
||||||
|
"//cc/toolchains:cc_toolchain_info.bzl",
|
||||||
|
"ActionTypeSetInfo",
|
||||||
|
)
|
||||||
|
|
||||||
|
visibility("//cc/toolchains/...")
|
||||||
|
|
||||||
|
def collect_provider(targets, provider):
|
||||||
|
"""Collects providers from a label list.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
targets: (list[Target]) An attribute from attr.label_list
|
||||||
|
provider: (provider) The provider to look up
|
||||||
|
Returns:
|
||||||
|
A list of the providers
|
||||||
|
"""
|
||||||
|
return [target[provider] for target in targets]
|
||||||
|
|
||||||
|
def collect_defaultinfo(targets):
|
||||||
|
"""Collects DefaultInfo from a label list.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
targets: (list[Target]) An attribute from attr.label_list
|
||||||
|
Returns:
|
||||||
|
A list of the associated defaultinfo
|
||||||
|
"""
|
||||||
|
return collect_provider(targets, DefaultInfo)
|
||||||
|
|
||||||
|
def _make_collector(provider, field):
|
||||||
|
def collector(targets, direct = [], transitive = []):
|
||||||
|
# Avoid mutating what was passed in.
|
||||||
|
transitive = transitive[:]
|
||||||
|
for value in collect_provider(targets, provider):
|
||||||
|
transitive.append(getattr(value, field))
|
||||||
|
return depset(direct = direct, transitive = transitive)
|
||||||
|
|
||||||
|
return collector
|
||||||
|
|
||||||
|
collect_action_types = _make_collector(ActionTypeSetInfo, "actions")
|
||||||
|
collect_files = _make_collector(DefaultInfo, "files")
|
|
@ -0,0 +1,25 @@
|
||||||
|
load("@rules_testing//lib:util.bzl", "util")
|
||||||
|
load("//cc/toolchains:args.bzl", "cc_args")
|
||||||
|
load("//tests/rule_based_toolchain:analysis_test_suite.bzl", "analysis_test_suite")
|
||||||
|
load(":args_test.bzl", "TARGETS", "TESTS")
|
||||||
|
|
||||||
|
util.helper_target(
|
||||||
|
cc_args,
|
||||||
|
name = "simple",
|
||||||
|
actions = ["//tests/rule_based_toolchain/actions:all_compile"],
|
||||||
|
additional_files = [
|
||||||
|
"//tests/rule_based_toolchain/testdata:file1",
|
||||||
|
"//tests/rule_based_toolchain/testdata:multiple",
|
||||||
|
],
|
||||||
|
args = [
|
||||||
|
"--foo",
|
||||||
|
"foo",
|
||||||
|
],
|
||||||
|
env = {"BAR": "bar"},
|
||||||
|
)
|
||||||
|
|
||||||
|
analysis_test_suite(
|
||||||
|
name = "test_suite",
|
||||||
|
targets = TARGETS,
|
||||||
|
tests = TESTS,
|
||||||
|
)
|
|
@ -0,0 +1,45 @@
|
||||||
|
# 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",
|
||||||
|
"ArgsInfo",
|
||||||
|
)
|
||||||
|
|
||||||
|
visibility("//tests/rule_based_toolchain/...")
|
||||||
|
|
||||||
|
def _test_simple_args_impl(env, targets):
|
||||||
|
simple = env.expect.that_target(targets.simple).provider(ArgsInfo)
|
||||||
|
simple.actions().contains_exactly([
|
||||||
|
targets.c_compile.label,
|
||||||
|
targets.cpp_compile.label,
|
||||||
|
])
|
||||||
|
simple.args().contains_exactly([targets.simple.label])
|
||||||
|
simple.env().contains_exactly({"BAR": "bar"})
|
||||||
|
simple.files().contains_exactly([
|
||||||
|
"tests/rule_based_toolchain/testdata/file1",
|
||||||
|
"tests/rule_based_toolchain/testdata/multiple1",
|
||||||
|
"tests/rule_based_toolchain/testdata/multiple2",
|
||||||
|
])
|
||||||
|
|
||||||
|
TARGETS = [
|
||||||
|
":simple",
|
||||||
|
"//tests/rule_based_toolchain/actions:c_compile",
|
||||||
|
"//tests/rule_based_toolchain/actions:cpp_compile",
|
||||||
|
]
|
||||||
|
|
||||||
|
TESTS = {
|
||||||
|
"simple_test": _test_simple_args_impl,
|
||||||
|
}
|
|
@ -20,11 +20,11 @@ load(
|
||||||
"ActionConfigSetInfo",
|
"ActionConfigSetInfo",
|
||||||
"ActionTypeInfo",
|
"ActionTypeInfo",
|
||||||
"ActionTypeSetInfo",
|
"ActionTypeSetInfo",
|
||||||
|
"AddArgsInfo",
|
||||||
|
"ArgsInfo",
|
||||||
"FeatureConstraintInfo",
|
"FeatureConstraintInfo",
|
||||||
"FeatureInfo",
|
"FeatureInfo",
|
||||||
"FeatureSetInfo",
|
"FeatureSetInfo",
|
||||||
"FlagGroupInfo",
|
|
||||||
"FlagSetInfo",
|
|
||||||
"MutuallyExclusiveCategoryInfo",
|
"MutuallyExclusiveCategoryInfo",
|
||||||
"ToolInfo",
|
"ToolInfo",
|
||||||
)
|
)
|
||||||
|
@ -94,22 +94,24 @@ _FeatureConstraintFactory = generate_factory(
|
||||||
)
|
)
|
||||||
|
|
||||||
# buildifier: disable=name-conventions
|
# buildifier: disable=name-conventions
|
||||||
_FlagGroupFactory = generate_factory(
|
_AddArgsFactory = generate_factory(
|
||||||
FlagGroupInfo,
|
AddArgsInfo,
|
||||||
"FlagGroupInfo",
|
"AddArgsInfo",
|
||||||
dict(
|
dict(
|
||||||
flags = subjects.collection,
|
args = subjects.collection,
|
||||||
|
files = subjects.depset_file,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# buildifier: disable=name-conventions
|
# buildifier: disable=name-conventions
|
||||||
_FlagSetFactory = generate_factory(
|
_ArgsFactory = generate_factory(
|
||||||
FlagSetInfo,
|
ArgsInfo,
|
||||||
"FlagSetInfo",
|
"ArgsInfo",
|
||||||
dict(
|
dict(
|
||||||
actions = ProviderDepset(_ActionTypeFactory),
|
actions = ProviderDepset(_ActionTypeFactory),
|
||||||
# Use a collection here because we don't want to
|
args = ProviderSequence(_AddArgsFactory),
|
||||||
flag_groups = subjects.collection,
|
env = subjects.dict,
|
||||||
|
files = subjects.depset_file,
|
||||||
requires_any_of = ProviderSequence(_FeatureConstraintFactory),
|
requires_any_of = ProviderSequence(_FeatureConstraintFactory),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -144,7 +146,7 @@ _ActionConfigFactory = generate_factory(
|
||||||
action = _ActionTypeFactory,
|
action = _ActionTypeFactory,
|
||||||
enabled = subjects.bool,
|
enabled = subjects.bool,
|
||||||
tools = ProviderSequence(_ToolFactory),
|
tools = ProviderSequence(_ToolFactory),
|
||||||
flag_sets = ProviderSequence(_FlagSetFactory),
|
flag_sets = ProviderSequence(_ArgsFactory),
|
||||||
implies = ProviderDepset(_FeatureFactory),
|
implies = ProviderDepset(_FeatureFactory),
|
||||||
files = subjects.depset_file,
|
files = subjects.depset_file,
|
||||||
),
|
),
|
||||||
|
@ -174,8 +176,8 @@ _ActionConfigSetFactory = struct(
|
||||||
FACTORIES = [
|
FACTORIES = [
|
||||||
_ActionTypeFactory,
|
_ActionTypeFactory,
|
||||||
_ActionTypeSetFactory,
|
_ActionTypeSetFactory,
|
||||||
_FlagGroupFactory,
|
_AddArgsFactory,
|
||||||
_FlagSetFactory,
|
_ArgsFactory,
|
||||||
_MutuallyExclusiveCategoryFactory,
|
_MutuallyExclusiveCategoryFactory,
|
||||||
_FeatureFactory,
|
_FeatureFactory,
|
||||||
_FeatureConstraintFactory,
|
_FeatureConstraintFactory,
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package(default_visibility = ["//tests/rule_based_toolchain:__subpackages__"])
|
||||||
|
|
||||||
|
exports_files(
|
||||||
|
glob(
|
||||||
|
["*"],
|
||||||
|
exclude = ["BUILD"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "multiple",
|
||||||
|
srcs = [
|
||||||
|
"multiple1",
|
||||||
|
"multiple2",
|
||||||
|
],
|
||||||
|
)
|
Loading…
Reference in New Issue