From c4676b9c90550b89c9b634109e9ba155a956b3dd Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Sat, 4 Jun 2022 05:41:37 -0700 Subject: [PATCH] Added TemplateVariableInfo to rust_toolchain --- rust/private/toolchain_utils.bzl | 25 ++++ rust/private/utils.bzl | 20 ++- rust/toolchain.bzl | 19 +++ rust/toolchain/BUILD.bazel | 6 +- .../unit/toolchain_make_variables/BUILD.bazel | 5 + test/unit/toolchain_make_variables/main.rs | 1 + .../toolchain_make_variables_test.bzl | 126 ++++++++++++++++++ 7 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 test/unit/toolchain_make_variables/BUILD.bazel create mode 100644 test/unit/toolchain_make_variables/main.rs create mode 100644 test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl diff --git a/rust/private/toolchain_utils.bzl b/rust/private/toolchain_utils.bzl index fcd4fb7029..4e32b6dde6 100644 --- a/rust/private/toolchain_utils.bzl +++ b/rust/private/toolchain_utils.bzl @@ -80,3 +80,28 @@ toolchain_files = rule( ], incompatible_use_toolchain_transition = True, ) + +def _current_rust_toolchain_impl(ctx): + toolchain = ctx.toolchains[str(Label("@rules_rust//rust:toolchain"))] + + return [ + toolchain, + toolchain.make_variables, + DefaultInfo( + files = depset([ + toolchain.rustc, + toolchain.rust_doc, + toolchain.rustfmt, + toolchain.cargo, + ]), + ), + ] + +current_rust_toolchain = rule( + doc = "A rule for exposing the current registered `rust_toolchain`.", + implementation = _current_rust_toolchain_impl, + toolchains = [ + str(Label("@rules_rust//rust:toolchain")), + ], + incompatible_use_toolchain_transition = True, +) diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl index 0ad8de9ee5..b3e8e809d3 100644 --- a/rust/private/utils.bzl +++ b/rust/private/utils.bzl @@ -186,12 +186,12 @@ def get_preferred_artifact(library_to_link, use_pic): ) def _expand_location(ctx, env, data): - """A trivial helper for `_expand_locations` + """A trivial helper for `expand_dict_value_locations` and `expand_list_element_locations` Args: ctx (ctx): The rule's context object env (str): The value possibly containing location macros to expand. - data (sequence of Targets): see `_expand_locations` + data (sequence of Targets): See one of the parent functions. Returns: string: The location-macro expanded version of the string. @@ -199,8 +199,12 @@ def _expand_location(ctx, env, data): for directive in ("$(execpath ", "$(location "): if directive in env: # build script runner will expand pwd to execroot for us - env = env.replace(directive, "${pwd}/" + directive) - return ctx.expand_location(env, data) + env = env.replace(directive, "$${pwd}/" + directive) + return ctx.expand_make_variables( + env, + ctx.expand_location(env, data), + {}, + ) def expand_dict_value_locations(ctx, env, data): """Performs location-macro expansion on string values. @@ -217,7 +221,9 @@ def expand_dict_value_locations(ctx, env, data): as compilation happens in a separate sandbox folder, so when it comes time to read the file at runtime, the path is no longer valid. - See [`expand_location`](https://docs.bazel.build/versions/main/skylark/lib/ctx.html#expand_location) for detailed documentation. + For detailed documentation, see: + - [`expand_location`](https://bazel.build/rules/lib/ctx#expand_location) + - [`expand_make_variables`](https://bazel.build/rules/lib/ctx#expand_make_variables) Args: ctx (ctx): The rule's context object @@ -238,7 +244,9 @@ def expand_list_element_locations(ctx, args, data): which process_wrapper and build_script_runner will expand at run time to the absolute path. - See [`expand_location`](https://docs.bazel.build/versions/main/skylark/lib/ctx.html#expand_location) for detailed documentation. + For detailed documentation, see: + - [`expand_location`](https://bazel.build/rules/lib/ctx#expand_location) + - [`expand_make_variables`](https://bazel.build/rules/lib/ctx#expand_make_variables) Args: ctx (ctx): The rule's context object diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 7d60256af5..90dea6e1b8 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -465,6 +465,24 @@ def _rust_toolchain_impl(ctx): sysroot_path = sysroot.sysroot_anchor.dirname sysroot_short_path, _, _ = sysroot.sysroot_anchor.short_path.rpartition("/") + # Variables for make variable expansion + make_variables = { + "RUSTC": sysroot.rustc.path, + "RUSTDOC": sysroot.rustdoc.path, + "RUST_DEFAULT_EDITION": ctx.attr.default_edition or "", + "RUST_SYSROOT": sysroot_path, + } + + if sysroot.cargo: + make_variables.update({ + "CARGO": sysroot.cargo.path, + }) + + if sysroot.rustfmt: + make_variables.update({ + "RUSTFMT": sysroot.rustfmt.path, + }) + toolchain = platform_common.ToolchainInfo( all_files = sysroot.all_files, binary_ext = ctx.attr.binary_ext, @@ -477,6 +495,7 @@ def _rust_toolchain_impl(ctx): env = ctx.attr.env, exec_triple = ctx.attr.exec_triple, libstd_and_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, ctx.attr.allocator_library), + make_variables = platform_common.TemplateVariableInfo(make_variables), os = ctx.attr.os, rust_doc = sysroot.rustdoc, rust_lib = sysroot.rust_std, # `rust_lib` is deprecated and only exists for legacy support. diff --git a/rust/toolchain/BUILD.bazel b/rust/toolchain/BUILD.bazel index 3b7ad50c83..dffc380360 100644 --- a/rust/toolchain/BUILD.bazel +++ b/rust/toolchain/BUILD.bazel @@ -1,4 +1,4 @@ -load("//rust/private:toolchain_utils.bzl", "toolchain_files") +load("//rust/private:toolchain_utils.bzl", "current_rust_toolchain", "toolchain_files") package(default_visibility = ["//visibility:public"]) @@ -90,6 +90,10 @@ alias( deprecation = "instead use `@rules_rust//rust/toolchain:current_rust_stdlib_files`", ) +current_rust_toolchain( + name = "current_rust_toolchain", +) + filegroup( name = "distro", srcs = [ diff --git a/test/unit/toolchain_make_variables/BUILD.bazel b/test/unit/toolchain_make_variables/BUILD.bazel new file mode 100644 index 0000000000..2534bd8be3 --- /dev/null +++ b/test/unit/toolchain_make_variables/BUILD.bazel @@ -0,0 +1,5 @@ +load(":toolchain_make_variables_test.bzl", "toolchain_make_variable_test_suite") + +toolchain_make_variable_test_suite( + name = "toolchain_make_variable_test_suite", +) diff --git a/test/unit/toolchain_make_variables/main.rs b/test/unit/toolchain_make_variables/main.rs new file mode 100644 index 0000000000..da0f5d925d --- /dev/null +++ b/test/unit/toolchain_make_variables/main.rs @@ -0,0 +1 @@ +pub fn main() {} diff --git a/test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl b/test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl new file mode 100644 index 0000000000..686d4cfe58 --- /dev/null +++ b/test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl @@ -0,0 +1,126 @@ +"""Tests for make variables provided by `rust_toolchain`""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest") +load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_test") +load("//test/unit:common.bzl", "assert_action_mnemonic", "assert_env_value") + +_ENV = { + "ENV_VAR_CARGO": "$(CARGO)", + "ENV_VAR_RUSTC": "$(RUSTC)", + "ENV_VAR_RUSTDOC": "$(RUSTDOC)", + "ENV_VAR_RUSTFMT": "$(RUSTFMT)", + "ENV_VAR_RUST_DEFAULT_EDITION": "$(RUST_DEFAULT_EDITION)", + "ENV_VAR_RUST_SYSROOT": "$(RUST_SYSROOT)", +} + +def _rustc_env_variable_expansion_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + action = target.actions[0] + + assert_action_mnemonic( + env = env, + action = action, + mnemonic = "Rustc", + ) + + toolchain = ctx.attr._current_rust_toolchain[platform_common.ToolchainInfo] + + expected_values = { + "ENV_VAR_CARGO": toolchain.cargo.path, + "ENV_VAR_RUSTC": toolchain.rustc.path, + "ENV_VAR_RUSTDOC": toolchain.rust_doc.path, + "ENV_VAR_RUSTFMT": toolchain.rustfmt.path, + "ENV_VAR_RUST_DEFAULT_EDITION": toolchain.default_edition or "", + "ENV_VAR_RUST_SYSROOT": toolchain.sysroot, + } + + for key in _ENV: + assert_env_value( + env = env, + action = action, + key = key, + value = expected_values[key], + ) + + return analysistest.end(env) + +rustc_env_variable_expansion_test = analysistest.make( + impl = _rustc_env_variable_expansion_test_impl, + attrs = { + "_current_rust_toolchain": attr.label( + doc = "The currently registered rust toolchain", + default = Label("//rust/toolchain:current_rust_toolchain"), + ), + }, +) + +def _define_targets(): + rust_library( + name = "library", + srcs = ["main.rs"], + toolchains = ["//rust/toolchain:current_rust_toolchain"], + rustc_env = _ENV, + edition = "2018", + ) + + rust_binary( + name = "binary", + srcs = ["main.rs"], + toolchains = ["//rust/toolchain:current_rust_toolchain"], + rustc_env = _ENV, + edition = "2018", + ) + + rust_test( + name = "integration_test", + srcs = ["main.rs"], + toolchains = ["//rust/toolchain:current_rust_toolchain"], + rustc_env = _ENV, + edition = "2018", + ) + + rust_test( + name = "unit_test", + crate = "library", + toolchains = ["//rust/toolchain:current_rust_toolchain"], + rustc_env = _ENV, + ) + +def toolchain_make_variable_test_suite(name): + """Defines a test suite + + Args: + name (str): The name of the test suite + """ + _define_targets() + + rustc_env_variable_expansion_test( + name = "rustc_env_variable_expansion_library_test", + target_under_test = ":library", + ) + + rustc_env_variable_expansion_test( + name = "rustc_env_variable_expansion_binary_test", + target_under_test = ":binary", + ) + + rustc_env_variable_expansion_test( + name = "rustc_env_variable_expansion_integration_test_test", + target_under_test = ":integration_test", + ) + + rustc_env_variable_expansion_test( + name = "rustc_env_variable_expansion_unit_test_test", + target_under_test = ":unit_test", + ) + + native.test_suite( + name = name, + tests = [ + ":rustc_env_variable_expansion_library_test", + ":rustc_env_variable_expansion_binary_test", + ":rustc_env_variable_expansion_integration_test_test", + ":rustc_env_variable_expansion_unit_test_test", + ], + )