Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cc/toolchains/args.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@ def _cc_args_impl(ctx):
formatted_env, used_format_vars = format_dict_values(
env = ctx.attr.env,
must_use = [], # checking for unused variables in done when formatting `args`.
format = {k: v for v, k in ctx.attr.format.items()},
format = {k: struct(__raw_string = v) for k, v in ctx.var.items()} | {k: v for v, k in ctx.attr.format.items()},
)

# Filter out variables from ctx.var which don't have to be used
used_format_vars = [v for v in used_format_vars if v in ctx.attr.format.values()]

for path in ctx.attr.allowlist_absolute_include_directories:
if not is_path_absolute(path):
fail("`{}` is not an absolute paths".format(path))
Expand Down
12 changes: 10 additions & 2 deletions cc/toolchains/impl/nested_args.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def nested_args_provider_from_ctx(ctx, maybe_used_vars = []):
return nested_args_provider(
label = ctx.label,
args = ctx.attr.args,
make_variables = ctx.var,
format = ctx.attr.format,
nested = collect_provider(ctx.attr.nested, NestedArgsInfo),
files = collect_files(ctx.attr.data),
Expand Down Expand Up @@ -125,6 +126,7 @@ def nested_args_provider(
requires_equal = None,
requires_equal_value = "",
maybe_used_vars = [],
make_variables = {},
fail = fail):
"""Creates a validated NestedArgsInfo.

Expand Down Expand Up @@ -153,6 +155,8 @@ def nested_args_provider(
requires_equal_value: (str) The value to compare the requires_equal
variable with
maybe_used_vars: (List[str]) A list of format variables that are not needed during args formatting.
make_variables: (dict[str, str]) Make variable substitutions from
ctx.var. {KEY} references in args are replaced with values.
fail: A fail function. Use only for testing.
Returns:
NestedArgsInfo
Expand All @@ -177,6 +181,8 @@ def nested_args_provider(
))
replacements[name] = target

make_replacements = {k: struct(__raw_string = v) for k, v in make_variables.items()}

# Intentionally ensure that we do not have to use the variable provided by
# iterate_over in the format string.
# For example, a valid use case is:
Expand All @@ -190,7 +196,7 @@ def nested_args_provider(
# )
formatted_args, _ = format_list(
args,
replacements,
make_replacements | replacements,
must_use = [var for var in format.values() if var not in maybe_used_vars],
fail = fail,
)
Expand Down Expand Up @@ -292,7 +298,9 @@ def _escape(s):
return s.replace("%", "%%")

def _format_target(target, fail = fail):
if VariableInfo in target:
if hasattr(target, "__raw_string"):
return _escape(target.__raw_string)
elif VariableInfo in target:
return "%%{%s}" % target[VariableInfo].name
elif DirectoryInfo in target:
return _escape(target[DirectoryInfo].path)
Expand Down
29 changes: 29 additions & 0 deletions tests/rule_based_toolchain/args/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ load("//cc/toolchains/impl:variables.bzl", "cc_variable", "types")
load("//tests/rule_based_toolchain:analysis_test_suite.bzl", "analysis_test_suite")
load("//tests/rule_based_toolchain:testing_rules.bzl", "expect_failure_test")
load(":args_test.bzl", "TARGETS", "TESTS")
load(":make_var_provider.bzl", "make_var_provider")

cc_variable(
name = "some_variable",
Expand Down Expand Up @@ -134,6 +135,34 @@ expect_failure_test(
target = ":bad_env_format_wrong_action",
)

make_var_provider(
name = "make_vars",
variables = {
"MY_PATH": "/usr/local",
"MY_FLAG": "-DFOO",
},
)

util.helper_target(
cc_args,
name = "with_make_vars",
actions = ["//tests/rule_based_toolchain/actions:all_compile"],
args = [
"--path={MY_PATH}",
"{MY_FLAG}",
],
toolchains = [":make_vars"],
)

util.helper_target(
cc_args,
name = "with_make_vars_env",
actions = ["//tests/rule_based_toolchain/actions:all_compile"],
args = ["--foo"],
env = {"MY_ENV": "{MY_PATH}/bin"},
toolchains = [":make_vars"],
)

analysis_test_suite(
name = "test_suite",
targets = TARGETS,
Expand Down
18 changes: 18 additions & 0 deletions tests/rule_based_toolchain/args/args_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ TARGETS = [
":env_only_requires",
":with_dir",
":with_dir_and_data",
":with_make_vars",
":with_make_vars_env",
":iterate_over_optional",
":good_env_format",
":good_env_format_optional",
Expand Down Expand Up @@ -322,6 +324,20 @@ def _good_env_format_test(env, targets):
)],
)])

def _with_make_vars_test(env, targets):
converted = env.expect.that_value(
convert_args(targets.with_make_vars[ArgsInfo]),
factory = _CONVERTED_ARGS,
)
converted.flag_sets().contains_exactly([flag_set(
actions = ["c_compile", "cpp_compile"],
flag_groups = [flag_group(flags = ["--path=/usr/local", "-DFOO"])],
)])

def _with_make_vars_env_test(env, targets):
make_vars_env = env.expect.that_target(targets.with_make_vars_env).provider(ArgsInfo)
make_vars_env.env().entries().contains_exactly({"MY_ENV": "/usr/local/bin"})

def _good_env_format_optional_test(env, targets):
"""Test that env formatting works with optional types."""
good_env_optional = env.expect.that_target(targets.good_env_format_optional).provider(ArgsInfo)
Expand Down Expand Up @@ -363,4 +379,6 @@ TESTS = {
"with_dir_and_data_test": _with_dir_and_data_test,
"good_env_format_test": _good_env_format_test,
"good_env_format_optional_test": _good_env_format_optional_test,
"with_make_vars_test": _with_make_vars_test,
"with_make_vars_env_test": _with_make_vars_env_test,
}
11 changes: 11 additions & 0 deletions tests/rule_based_toolchain/args/make_var_provider.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Helper rule for providing TemplateVariableInfo in tests."""

def _make_var_provider_impl(ctx):
return [platform_common.TemplateVariableInfo(ctx.attr.variables)]

make_var_provider = rule(
implementation = _make_var_provider_impl,
attrs = {
"variables": attr.string_dict(),
},
)
19 changes: 19 additions & 0 deletions tests/rule_based_toolchain/nested_args/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
load("//cc/toolchains:nested_args.bzl", "cc_nested_args")
load("//cc/toolchains/impl:variables.bzl", "cc_variable", "types")
load("//tests/rule_based_toolchain:analysis_test_suite.bzl", "analysis_test_suite")
load("//tests/rule_based_toolchain/args:make_var_provider.bzl", "make_var_provider")
load(":nested_args_test.bzl", "TARGETS", "TESTS")

cc_variable(
Expand All @@ -12,6 +14,23 @@ cc_variable(
type = types.list(types.string),
)

make_var_provider(
name = "make_vars",
variables = {
"MY_PATH": "/usr/local",
"MY_FLAG": "-DFOO",
},
)

cc_nested_args(
name = "nested_with_make_vars",
args = [
"--path={MY_PATH}",
"{MY_FLAG}",
],
toolchains = [":make_vars"],
)

analysis_test_suite(
name = "test_suite",
targets = TARGETS,
Expand Down
7 changes: 7 additions & 0 deletions tests/rule_based_toolchain/nested_args/nested_args_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo")
load("//cc:cc_toolchain_config_lib.bzl", "flag_group", "variable_with_value")
load("//cc/toolchains:cc_toolchain_info.bzl", "NestedArgsInfo")
load(
"//cc/toolchains/impl:nested_args.bzl",
"FORMAT_ARGS_ERR",
Expand Down Expand Up @@ -225,9 +226,14 @@ def _requires_types_test(env, targets):
flags = ["--foo=%{foo}"],
))

def _nested_make_vars_test(env, targets):
nested = env.expect.that_target(targets.nested_with_make_vars).provider(NestedArgsInfo)
nested.legacy_flag_group().equals(flag_group(flags = ["--path=/usr/local", "-DFOO"]))

TARGETS = [
":foo",
":my_list",
":nested_with_make_vars",
"//tests/rule_based_toolchain/testdata:directory",
"//tests/rule_based_toolchain/testdata:bin_wrapper",
]
Expand All @@ -236,4 +242,5 @@ TESTS = {
"format_args_test": _format_args_test,
"iterate_over_test": _iterate_over_test,
"requires_types_test": _requires_types_test,
"nested_make_vars_test": _nested_make_vars_test,
}