From 4bf51b3c790c4c3d0ee8c28c15b7307b64a7069a Mon Sep 17 00:00:00 2001 From: RS Date: Thu, 1 Jul 2021 13:02:28 -0700 Subject: [PATCH] Expand arg location in rustc_flags attribute (#809) Expand locations in rustc_flags. Fixes #801. --- cargo/cargo_build_script.bzl | 4 +- docs/defs.md | 14 ++--- docs/flatten.md | 14 ++--- examples/flag_locations/BUILD.bazel | 23 ++++++++ examples/flag_locations/main.rs | 9 ++++ rust/private/rust.bzl | 13 +++-- rust/private/rustc.bzl | 19 ++++--- rust/private/utils.bzl | 25 ++++++++- test/unit/location_expansion/BUILD.bazel | 4 ++ .../location_expansion_test.bzl | 54 +++++++++++++++++++ test/unit/location_expansion/mylibrary.rs | 1 + util/launcher/launcher_main.rs | 2 +- 12 files changed, 155 insertions(+), 27 deletions(-) create mode 100644 examples/flag_locations/BUILD.bazel create mode 100644 examples/flag_locations/main.rs create mode 100644 test/unit/location_expansion/BUILD.bazel create mode 100644 test/unit/location_expansion/location_expansion_test.bzl create mode 100644 test/unit/location_expansion/mylibrary.rs diff --git a/cargo/cargo_build_script.bzl b/cargo/cargo_build_script.bzl index 1ac0f0dddd..7500920435 100644 --- a/cargo/cargo_build_script.bzl +++ b/cargo/cargo_build_script.bzl @@ -8,7 +8,7 @@ load("//rust:rust.bzl", "rust_binary") load("//rust/private:rustc.bzl", "BuildInfo", "get_compilation_mode_opts", "get_linker_and_args") # buildifier: disable=bzl-visibility -load("//rust/private:utils.bzl", "expand_locations", "find_cc_toolchain", "find_toolchain", "name_to_crate_name") +load("//rust/private:utils.bzl", "expand_dict_value_locations", "find_cc_toolchain", "find_toolchain", "name_to_crate_name") def get_cc_compile_env(cc_toolchain, feature_configuration): """Gather cc environment variables from the given `cc_toolchain` @@ -117,7 +117,7 @@ def _build_script_impl(ctx): for f in ctx.attr.crate_features: env["CARGO_FEATURE_" + f.upper().replace("-", "_")] = "1" - env.update(expand_locations( + env.update(expand_dict_value_locations( ctx, ctx.attr.build_script_env, getattr(ctx.attr, "data", []) + diff --git a/docs/defs.md b/docs/defs.md index e486b30605..6a846d27a1 100644 --- a/docs/defs.md +++ b/docs/defs.md @@ -112,7 +112,7 @@ Run the benchmark test using: `bazel run //fibonacci:fibonacci_bench`. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -230,7 +230,7 @@ Hello world | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -325,7 +325,7 @@ INFO: Elapsed time: 1.245s, Critical Path: 1.01s | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -359,7 +359,7 @@ Builds a Rust proc-macro crate. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -401,7 +401,7 @@ When building the whole binary in Bazel, use `rust_library` instead. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -443,7 +443,7 @@ When building the whole binary in Bazel, use `rust_library` instead. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -605,7 +605,7 @@ Run the test with `bazel build //hello_lib:hello_lib_test`. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | use_libtest_harness | Whether to use libtest. | Boolean | optional | True | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | diff --git a/docs/flatten.md b/docs/flatten.md index 475af2850c..d6ae3a08aa 100644 --- a/docs/flatten.md +++ b/docs/flatten.md @@ -203,7 +203,7 @@ Run the benchmark test using: `bazel run //fibonacci:fibonacci_bench`. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -321,7 +321,7 @@ Hello world | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -671,7 +671,7 @@ INFO: Elapsed time: 1.245s, Critical Path: 1.01s | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -705,7 +705,7 @@ Builds a Rust proc-macro crate. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -847,7 +847,7 @@ When building the whole binary in Bazel, use `rust_library` instead. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -889,7 +889,7 @@ When building the whole binary in Bazel, use `rust_library` instead. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | @@ -1070,7 +1070,7 @@ Run the test with `bazel build //hello_lib:hello_lib_test`. | proc_macro_deps | List of rust_library targets with kind proc-macro used to help build this library target. | List of labels | optional | [] | | rustc_env | Dictionary of additional "key": "value" environment variables to set for rustc.

rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the location of a generated file or external tool. Cargo build scripts that wish to expand locations should use cargo_build_script()'s build_script_env argument instead, as build scripts are run in a different environment - see cargo_build_script()'s documentation for more. | Dictionary: String -> String | optional | {} | | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | -| rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | +| rustc_flags | List of compiler flags passed to rustc.

These strings are subject to Make variable expansion for predefined source/output path variables like $location, $execpath, and $rootpath. This expansion is useful if you wish to pass a generated file of arguments to rustc: @$(location //package:target). | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | | use_libtest_harness | Whether to use libtest. | Boolean | optional | True | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | diff --git a/examples/flag_locations/BUILD.bazel b/examples/flag_locations/BUILD.bazel new file mode 100644 index 0000000000..ed54cdae4c --- /dev/null +++ b/examples/flag_locations/BUILD.bazel @@ -0,0 +1,23 @@ +load( + "@rules_rust//rust:rust.bzl", + "rust_test", +) + +# generate a file containing cfg flags +genrule( + name = "flag_generator", + outs = ["generated_flag.data"], + cmd = "echo --cfg=test_flag > $@", +) + +rust_test( + name = "test", + srcs = [ + "main.rs", + ], + data = [":flag_generator"], + edition = "2018", + rustc_flags = [ + "@$(location :flag_generator)", + ], +) diff --git a/examples/flag_locations/main.rs b/examples/flag_locations/main.rs new file mode 100644 index 0000000000..cee1077015 --- /dev/null +++ b/examples/flag_locations/main.rs @@ -0,0 +1,9 @@ +#[test] +fn test() { + // we should be able to read rustc args from a generated file + if cfg!(test_flag) { + return; + } + + unreachable!(); +} diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 45a429997d..0a154274fc 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -20,7 +20,7 @@ load( "crate_name_from_attr", "dedent", "determine_output_hash", - "expand_locations", + "expand_dict_value_locations", "find_toolchain", ) @@ -340,7 +340,7 @@ def _create_test_launcher(ctx, toolchain, output, providers): # Expand the environment variables and write them to a file environ_file = ctx.actions.declare_file(launcher_filename + ".launchfiles/env") - environ = expand_locations( + environ = expand_dict_value_locations( ctx, getattr(ctx.attr, "env", {}), data, @@ -620,7 +620,14 @@ _common_attrs = { """), ), "rustc_flags": attr.string_list( - doc = "List of compiler flags passed to `rustc`.", + doc = dedent("""\ + List of compiler flags passed to `rustc`. + + These strings are subject to Make variable expansion for predefined + source/output path variables like `$location`, `$execpath`, and `$rootpath`. + This expansion is useful if you wish to pass a generated file of + arguments to rustc: `@$(location //package:target)`. + """), ), # TODO(stardoc): How do we provide additional documentation to an inherited attribute? # "name": attr.string( diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 367474d403..55a07ab3c4 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -21,7 +21,8 @@ load("//rust/private:common.bzl", "rust_common") load( "//rust/private:utils.bzl", "crate_name_from_attr", - "expand_locations", + "expand_dict_value_locations", + "expand_list_element_locations", "find_cc_toolchain", "get_lib_name", "get_preferred_artifact", @@ -438,9 +439,16 @@ def construct_arguments( # Tell Rustc where to find the standard library args.add_all(rust_lib_paths, before_each = "-L", format_each = "%s") - args.add_all(rust_flags) - args.add_all(getattr(attr, "rustc_flags", [])) + + data_paths = getattr(attr, "data", []) + getattr(attr, "compile_data", []) + args.add_all( + expand_list_element_locations( + ctx, + getattr(attr, "rustc_flags", []), + data_paths, + ), + ) add_edition_flags(args, crate_info) # Link! @@ -471,11 +479,10 @@ def construct_arguments( env["CARGO_BIN_EXE_" + dep_crate_info.output.basename] = dep_crate_info.output.short_path # Update environment with user provided variables. - env.update(expand_locations( + env.update(expand_dict_value_locations( ctx, crate_info.rustc_env, - getattr(attr, "data", []) + - getattr(attr, "compile_data", []), + data_paths, )) # This empty value satisfies Clippy, which otherwise complains about the diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl index 7d22208d63..30b8aee1c2 100644 --- a/rust/private/utils.bzl +++ b/rust/private/utils.bzl @@ -152,7 +152,7 @@ def _expand_location(ctx, env, data): env = env.replace(directive, "${pwd}/" + directive) return ctx.expand_location(env, data) -def expand_locations(ctx, env, data): +def expand_dict_value_locations(ctx, env, data): """Performs location-macro expansion on string values. $(execroot ...) and $(location ...) are prefixed with ${pwd}, @@ -167,6 +167,8 @@ def expand_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. + Args: ctx (ctx): The rule's context object env (dict): A dict whose values we iterate over @@ -179,6 +181,27 @@ def expand_locations(ctx, env, data): """ return dict([(k, _expand_location(ctx, v, data)) for (k, v) in env.items()]) +def expand_list_element_locations(ctx, args, data): + """Performs location-macro expansion on a list of string values. + + $(execroot ...) and $(location ...) are prefixed with ${pwd}, + 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. + + Args: + ctx (ctx): The rule's context object + args (list): A list we iterate over + data (sequence of Targets): The targets which may be referenced by + location macros. This is expected to be the `data` attribute of + the target, though may have other targets or attributes mixed in. + + Returns: + list: A list of arguments with expanded location macros + """ + return [_expand_location(ctx, arg, data) for arg in args] + def name_to_crate_name(name): """Converts a build target's name into the name of its associated crate. diff --git a/test/unit/location_expansion/BUILD.bazel b/test/unit/location_expansion/BUILD.bazel new file mode 100644 index 0000000000..83bf6c6ed1 --- /dev/null +++ b/test/unit/location_expansion/BUILD.bazel @@ -0,0 +1,4 @@ +load(":location_expansion_test.bzl", "location_expansion_test_suite") + +############################ UNIT TESTS ############################# +location_expansion_test_suite(name = "location_expansion_test_suite") diff --git a/test/unit/location_expansion/location_expansion_test.bzl b/test/unit/location_expansion/location_expansion_test.bzl new file mode 100644 index 0000000000..c2aa1940e6 --- /dev/null +++ b/test/unit/location_expansion/location_expansion_test.bzl @@ -0,0 +1,54 @@ +"""Unittest to verify location expansion in rustc flags""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest") +load("//rust:defs.bzl", "rust_library") +load("//test/unit:common.bzl", "assert_action_mnemonic", "assert_argv_contains") + +def _location_expansion_rustc_flags_test(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + action = tut.actions[0] + argv = action.argv + assert_action_mnemonic(env, action, "Rustc") + assert_argv_contains(env, action, "test/unit/location_expansion/mylibrary.rs") + expected = "@${pwd}/" + ctx.bin_dir.path + "/test/unit/location_expansion/generated_flag.data" + assert_argv_contains(env, action, expected) + return analysistest.end(env) + +location_expansion_rustc_flags_test = analysistest.make(_location_expansion_rustc_flags_test) + +def _location_expansion_test(): + native.genrule( + name = "flag_generator", + outs = ["generated_flag.data"], + cmd = "echo --cfg=test_flag > $@", + ) + + rust_library( + name = "mylibrary", + srcs = ["mylibrary.rs"], + rustc_flags = [ + "@$(location :flag_generator)", + ], + compile_data = [":flag_generator"], + ) + + location_expansion_rustc_flags_test( + name = "location_expansion_rustc_flags_test", + target_under_test = ":mylibrary", + ) + +def location_expansion_test_suite(name): + """Entry-point macro called from the BUILD file. + + Args: + name: Name of the macro. + """ + _location_expansion_test() + + native.test_suite( + name = name, + tests = [ + ":location_expansion_rustc_flags_test", + ], + ) diff --git a/test/unit/location_expansion/mylibrary.rs b/test/unit/location_expansion/mylibrary.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/test/unit/location_expansion/mylibrary.rs @@ -0,0 +1 @@ + diff --git a/util/launcher/launcher_main.rs b/util/launcher/launcher_main.rs index 10a2a09ff8..02ffbf2d7d 100644 --- a/util/launcher/launcher_main.rs +++ b/util/launcher/launcher_main.rs @@ -22,7 +22,7 @@ fn environ() -> BTreeMap { let file = File::open(env_path).expect("Failed to load the environment file"); // Variables will have the `${pwd}` variable replaced which is rendered by - // `@rules_rust//rust/private:util.bzl::expand_locations` + // `@rules_rust//rust/private:util.bzl::expand_dict_value_locations` let pwd = std::env::current_dir().expect("Failed to get current working directory"); let pwd_str = pwd.to_string_lossy();