diff --git a/rust/private/BUILD.bazel b/rust/private/BUILD.bazel index 71a4105dde..8b3f729991 100644 --- a/rust/private/BUILD.bazel +++ b/rust/private/BUILD.bazel @@ -1,4 +1,5 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load("@bazel_skylib//rules:common_settings.bzl", "string_setting") load("//rust/private:rust_analyzer.bzl", "rust_analyzer_detect_sysroot") load("//rust/private:rustc.bzl", "is_proc_macro_dep", "is_proc_macro_dep_enabled") load("//rust/private:stamp.bzl", "stamp_build_setting") @@ -52,6 +53,24 @@ is_proc_macro_dep_enabled( visibility = ["//visibility:public"], ) +# The scope of the crate being built. +# +# This setting is not used internally. It announces to the dependencies of rust crates +# (including toolchains) how their outputs are being used, to allow e.g. passing different +# copts to a cc_library when it is part of a crate or a procedure macro. +# +# We specialize proc macro, because it must be ABI compatible with rustc itself. +string_setting( + name = "crate_scope", + build_setting_default = "none", + values = [ + "none", # Not building a rust crate or a dep of rust crate + "proc_macro", # Building a proc macro or a dep of proc macro + "regular", # Building a regular crate or a (non-proc-macro) dep of such + ], + visibility = ["//rust/settings:__pkg__"], +) + rust_analyzer_detect_sysroot( name = "rust_analyzer_detect_sysroot", visibility = ["//visibility:public"], diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 74d458eef9..593f7bb05a 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -526,6 +526,34 @@ def _stamp_attribute(default_value): values = [1, 0, -1], ) +def _crate_scope_transition_impl(settings, attr): + if hasattr(attr, "_change_crate_scope"): + return {"//rust/private:crate_scope": attr._change_crate_scope} + if settings["//rust/private:crate_scope"] == "proc_macro": + # the whole transitive closure of a proc_macro should be the proc_macro scope, + # except that it is reset by either the _change_crate_scope attr above or the + # _crate_scope_reset_transition below. + return {"//rust/private:crate_scope": "proc_macro"} + return {"//rust/private:crate_scope": "regular"} + +_crate_scope_transition_inputs = ["//rust/private:crate_scope"] +_crate_scope_transition_outputs = ["//rust/private:crate_scope"] + +_crate_scope_transition = transition( + implementation = _crate_scope_transition_impl, + inputs = _crate_scope_transition_inputs, + outputs = _crate_scope_transition_outputs, +) + +def _crate_scope_reset_transition_impl(_settings, _attr): + return {"//rust/private:crate_scope": "none"} + +_crate_scope_reset_transition = transition( + implementation = _crate_scope_reset_transition_impl, + inputs = [], + outputs = _crate_scope_transition_outputs, +) + # Internal attributes core to Rustc actions. RUSTC_ATTRS = { "_error_format": attr.label( @@ -617,6 +645,7 @@ _common_attrs = { or the single file in `srcs` if `srcs` contains only one file. """), allow_single_file = [".rs"], + cfg = _crate_scope_reset_transition, ), "data": attr.label_list( doc = dedent("""\ @@ -627,6 +656,7 @@ _common_attrs = { in the runfiles. """), allow_files = True, + cfg = _crate_scope_reset_transition, ), "deps": attr.label_list( doc = dedent("""\ @@ -683,6 +713,7 @@ _common_attrs = { `NAME={WORKSPACE_STATUS_VARIABLE}`. """), allow_files = True, + cfg = _crate_scope_reset_transition, ), "rustc_flags": attr.string_list( doc = dedent("""\ @@ -711,6 +742,7 @@ _common_attrs = { # non-builtin rulesets is undocumented outside of the bazel source: # https://github.com/bazelbuild/bazel/blob/7.1.1/src/main/java/com/google/devtools/build/lib/packages/Attribute.java#L102 flags = ["DIRECT_COMPILE_TIME_INPUT"], + cfg = _crate_scope_reset_transition, ), "stamp": _stamp_attribute( default_value = 0, @@ -719,6 +751,9 @@ _common_attrs = { doc = "A version to inject in the cargo environment variable.", default = "0.0.0", ), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), "_stamp_flag": attr.label( doc = "A setting used to determine whether or not the `--stamp` flag is enabled", default = Label("//rust/private:stamp"), @@ -828,6 +863,7 @@ rust_library = rule( ), }, fragments = ["cpp"], + cfg = _crate_scope_transition, toolchains = [ str(Label("//rust:toolchain_type")), "@bazel_tools//tools/cpp:toolchain_type", @@ -901,16 +937,16 @@ rust_library = rule( def _rust_static_library_transition_impl(settings, attr): return { "//command_line_option:platforms": str(attr.platform) if attr.platform else settings["//command_line_option:platforms"], - } + } | _crate_scope_transition_impl(settings, attr) _rust_static_library_transition = transition( implementation = _rust_static_library_transition_impl, inputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_inputs, outputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_outputs, ) rust_static_library = rule( @@ -920,9 +956,6 @@ rust_static_library = rule( doc = "Optional platform to transition the static library to.", default = None, ), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), }, fragments = ["cpp"], cfg = _rust_static_library_transition, @@ -950,16 +983,16 @@ rust_static_library = rule( def _rust_shared_library_transition_impl(settings, attr): return { "//command_line_option:platforms": str(attr.platform) if attr.platform else settings["//command_line_option:platforms"], - } + } | _crate_scope_transition_impl(settings, attr) _rust_shared_library_transition = transition( implementation = _rust_shared_library_transition_impl, inputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_inputs, outputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_outputs, ) rust_shared_library = rule( @@ -969,9 +1002,6 @@ rust_shared_library = rule( doc = "Optional platform to transition the shared library to.", default = None, ), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), "_use_grep_includes": attr.bool(default = True), }, fragments = ["cpp"], @@ -1018,9 +1048,7 @@ rust_proc_macro = rule( # https://docs.bazel.build/versions/main/skylark/config.html#user-defined-transitions. attrs = dict( _common_attrs.items(), - _allowlist_function_transition = attr.label( - default = Label("//tools/allowlists/function_transition_allowlist"), - ), + _change_crate_scope = attr.string(default = "proc_macro"), deps = attr.label_list( doc = dedent("""\ List of other libraries to be linked to this library target. @@ -1032,6 +1060,7 @@ rust_proc_macro = rule( ), ), fragments = ["cpp"], + cfg = _crate_scope_transition, toolchains = [ str(Label("//rust:toolchain_type")), "@bazel_tools//tools/cpp:toolchain_type", @@ -1074,6 +1103,7 @@ _rust_binary_attrs = { Link script to forward into linker via rustc options. """), allow_single_file = True, + cfg = _crate_scope_reset_transition, ), "out_binary": attr.bool( doc = ( @@ -1090,16 +1120,16 @@ _rust_binary_attrs = { def _rust_binary_transition_impl(settings, attr): return { "//command_line_option:platforms": str(attr.platform) if attr.platform else settings["//command_line_option:platforms"], - } + } | _crate_scope_transition_impl(settings, attr) _rust_binary_transition = transition( implementation = _rust_binary_transition_impl, inputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_inputs, outputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_outputs, ) rust_binary = rule( @@ -1110,9 +1140,6 @@ rust_binary = rule( doc = "Optional platform to transition the binary to.", default = None, ), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), }, executable = True, fragments = ["cpp"], @@ -1252,9 +1279,7 @@ rust_binary_without_process_wrapper = rule( doc = "Optional platform to transition the binary to.", default = None, ), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), + "_change_crate_scope": attr.string(default = "regular"), }), executable = True, fragments = ["cpp"], @@ -1268,8 +1293,11 @@ rust_binary_without_process_wrapper = rule( rust_library_without_process_wrapper = rule( implementation = _rust_library_impl, provides = COMMON_PROVIDERS, - attrs = dict(_common_attrs_for_binary_without_process_wrapper(_common_attrs).items()), + attrs = _common_attrs_for_binary_without_process_wrapper(_common_attrs | { + "_change_crate_scope": attr.string(default = "regular"), + }), fragments = ["cpp"], + cfg = _crate_scope_transition, toolchains = [ str(Label("//rust:toolchain_type")), "@bazel_tools//tools/cpp:toolchain_type", @@ -1279,16 +1307,16 @@ rust_library_without_process_wrapper = rule( def _rust_test_transition_impl(settings, attr): return { "//command_line_option:platforms": str(attr.platform) if attr.platform else settings["//command_line_option:platforms"], - } + } | _crate_scope_transition_impl(settings, attr) _rust_test_transition = transition( implementation = _rust_test_transition_impl, inputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_inputs, outputs = [ "//command_line_option:platforms", - ], + ] + _crate_scope_transition_outputs, ) rust_test = rule( @@ -1299,9 +1327,6 @@ rust_test = rule( doc = "Optional platform to transition the test to.", default = None, ), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), }, executable = True, fragments = ["cpp"], diff --git a/rust/private/rustdoc_test.bzl b/rust/private/rustdoc_test.bzl index a338518038..dd67d245db 100644 --- a/rust/private/rustdoc_test.bzl +++ b/rust/private/rustdoc_test.bzl @@ -20,7 +20,7 @@ load("//rust/private:providers.bzl", "CrateInfo") load("//rust/private:rustdoc.bzl", "rustdoc_compile_action") load("//rust/private:utils.bzl", "dedent", "find_toolchain", "transform_deps") -def _construct_writer_arguments(ctx, test_runner, opt_test_params, action, crate_info): +def _construct_writer_arguments(ctx, test_runner, opt_test_params, action): """Construct arguments and environment variables specific to `rustdoc_test_writer`. This is largely solving for the fact that tests run from a runfiles directory @@ -32,7 +32,6 @@ def _construct_writer_arguments(ctx, test_runner, opt_test_params, action, crate test_runner (File): The test_runner output file declared by `rustdoc_test`. opt_test_params (File): An output file we can optionally use to store params for `rustdoc`. action (struct): Action arguments generated by `rustdoc_compile_action`. - crate_info (CrateInfo): The provider of the crate who's docs are being tested. Returns: tuple: A tuple of `rustdoc_test_writer` specific inputs @@ -64,29 +63,13 @@ def _construct_writer_arguments(ctx, test_runner, opt_test_params, action, crate # Collect and dedupe all of the file roots in a list before appending # them to args to prevent generating a large amount of identical args - roots = [] - root = crate_info.output.root.path - if not root in roots: - roots.append(root) - for dep in crate_info.deps.to_list() + crate_info.proc_macro_deps.to_list(): - dep_crate_info = getattr(dep, "crate_info", None) - dep_dep_info = getattr(dep, "dep_info", None) - if dep_crate_info: - root = dep_crate_info.output.root.path - if not root in roots: - roots.append(root) - if dep_dep_info: - for direct_dep in dep_dep_info.direct_crates.to_list(): - root = direct_dep.dep.output.root.path - if not root in roots: - roots.append(root) - for transitive_dep in dep_dep_info.transitive_crates.to_list(): - root = transitive_dep.output.root.path - if not root in roots: - roots.append(root) - - for root in roots: - writer_args.add("--strip_substring={}/".format(root)) + roots = {} + for input in action.inputs.to_list(): + roots[input.root.path] = None + + for root in roots.keys(): + if root: + writer_args.add("--strip_substring={}/".format(root)) # Indicate that the rustdoc_test args are over. writer_args.add("--") @@ -165,7 +148,6 @@ def _rust_doc_test_impl(ctx): test_runner = test_runner, opt_test_params = opt_test_params, action = action, - crate_info = crate_info, ) # Allow writer environment variables to override those from the action. diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index 8fb46461d8..aa52f38c15 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -49,6 +49,27 @@ bzl_library( ], ) +config_setting( + name = "non_rust_scope", + flag_values = { + "//rust/private:crate_scope": "none", + }, +) + +config_setting( + name = "proc_macro_scope", + flag_values = { + "//rust/private:crate_scope": "proc_macro", + }, +) + +config_setting( + name = "regular_crate_scope", + flag_values = { + "//rust/private:crate_scope": "regular", + }, +) + capture_clippy_output() clippy_flag() diff --git a/test/crate_scope/BUILD.bazel b/test/crate_scope/BUILD.bazel new file mode 100644 index 0000000000..fb849a40a2 --- /dev/null +++ b/test/crate_scope/BUILD.bazel @@ -0,0 +1,69 @@ +load("//rust:defs.bzl", "rust_library", "rust_proc_macro", "rust_test") + +rust_test( + name = "proc_macro_data_test", + srcs = select({ + "//rust/settings:regular_crate_scope": ["rust_test.rs"], + # Analysis fails if rust_test doesn't set the condition above. + }), + edition = "2021", + proc_macro_deps = [ + ":rust_proc_macro", + ], + deps = [ + ":nonmacro_library", + ], +) + +rust_library( + name = "nonmacro_library", + srcs = select({ + "//rust/settings:regular_crate_scope": ["nonmacro_library.rs"], + # Analysis fails if rust_library doesn't set the condition above. + }), + edition = "2021", + proc_macro_deps = [ + ":rust_proc_macro", + ], +) + +rust_proc_macro( + name = "rust_proc_macro", + srcs = ["rust_proc_macro.rs"], + data = select({ + "//rust/settings:proc_macro_scope": [":proc_macro_data"], + # Analysis fails if rust_proc_macro doesn't set the condition above. + }), + edition = "2021", + rustc_env = {"CARGO_MANIFEST_DIR": package_name()}, + deps = [ + ":proc_macro_helper", + ], +) + +rust_library( + name = "proc_macro_helper", + srcs = ["proc_macro_helper.rs"], + data = select({ + "//rust/settings:proc_macro_scope": [":helper_data"], + "//rust/settings:regular_crate_scope": [], + }), + edition = "2021", + rustc_env = {"CARGO_MANIFEST_DIR": package_name()}, +) + +filegroup( + name = "proc_macro_data", + srcs = select({ + "//rust/settings:non_rust_scope": ["proc_macro_data.txt"], + # Analysis fails if the data attribute doesn't reset the condition above. + }), +) + +filegroup( + name = "helper_data", + srcs = select({ + "//rust/settings:non_rust_scope": ["helper_data.txt"], + # Analysis fails if the data attribute doesn't reset the condition above. + }), +) diff --git a/test/crate_scope/helper_data.txt b/test/crate_scope/helper_data.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/crate_scope/nonmacro_library.rs b/test/crate_scope/nonmacro_library.rs new file mode 100644 index 0000000000..af5354ae19 --- /dev/null +++ b/test/crate_scope/nonmacro_library.rs @@ -0,0 +1,3 @@ +rust_proc_macro::ensure_proc_macro_data_exists!(); + +pub use rust_proc_macro::ensure_proc_macro_data_exists; diff --git a/test/crate_scope/proc_macro_data.txt b/test/crate_scope/proc_macro_data.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/crate_scope/proc_macro_helper.rs b/test/crate_scope/proc_macro_helper.rs new file mode 100644 index 0000000000..5626499984 --- /dev/null +++ b/test/crate_scope/proc_macro_helper.rs @@ -0,0 +1,6 @@ +use std::path::Path; + +pub fn ensure_helper_data_exists() { + let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("helper_data.txt"); + assert!(path.exists(), "not found: {}", path.display()); +} diff --git a/test/crate_scope/rust_proc_macro.rs b/test/crate_scope/rust_proc_macro.rs new file mode 100644 index 0000000000..a9ae1523a4 --- /dev/null +++ b/test/crate_scope/rust_proc_macro.rs @@ -0,0 +1,12 @@ +use proc_macro::TokenStream; +use std::path::Path; + +#[proc_macro] +pub fn ensure_proc_macro_data_exists(_input: TokenStream) -> TokenStream { + let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("proc_macro_data.txt"); + assert!(path.exists(), "not found: {}", path.display()); + + proc_macro_helper::ensure_helper_data_exists(); + + TokenStream::new() +} diff --git a/test/crate_scope/rust_test.rs b/test/crate_scope/rust_test.rs new file mode 100644 index 0000000000..c2ecb52bf8 --- /dev/null +++ b/test/crate_scope/rust_test.rs @@ -0,0 +1 @@ +nonmacro_library::ensure_proc_macro_data_exists!(); diff --git a/test/unit/channel_transitions/channel_transiitons_test.bzl b/test/unit/channel_transitions/channel_transiitons_test.bzl index f0bc165880..cae5fcebeb 100644 --- a/test/unit/channel_transitions/channel_transiitons_test.bzl +++ b/test/unit/channel_transitions/channel_transiitons_test.bzl @@ -5,17 +5,14 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary") load( "//test/unit:common.bzl", - "assert_action_mnemonic", "assert_argv_contains", "assert_argv_contains_not", ) def _channel_transition_test_impl(ctx, is_nightly): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] if is_nightly: assert_argv_contains(env, action, "-Zunstable-options") diff --git a/test/unit/codegen_units/codegen_units_test_suite.bzl b/test/unit/codegen_units/codegen_units_test_suite.bzl index d2cb238fe6..04634a7e66 100644 --- a/test/unit/codegen_units/codegen_units_test_suite.bzl +++ b/test/unit/codegen_units/codegen_units_test_suite.bzl @@ -5,7 +5,6 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary", "rust_library") load( "//test/unit:common.bzl", - "assert_action_mnemonic", "assert_argv_contains", "assert_argv_contains_prefix_not", ) @@ -14,10 +13,8 @@ _EXPECTED_VALUE = 11 def _codegen_units_test_impl(ctx, enabled = True): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] if enabled: assert_argv_contains(env, action, "-Ccodegen-units={}".format(_EXPECTED_VALUE)) diff --git a/test/unit/location_expansion/location_expansion_test.bzl b/test/unit/location_expansion/location_expansion_test.bzl index 69ecf97324..1134f71975 100644 --- a/test/unit/location_expansion/location_expansion_test.bzl +++ b/test/unit/location_expansion/location_expansion_test.bzl @@ -3,15 +3,13 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest") load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_library") -load("//test/unit:common.bzl", "assert_action_mnemonic", "assert_argv_contains") +load("//test/unit:common.bzl", "assert_argv_contains") def _location_expansion_rustc_flags_test(ctx): env = analysistest.begin(ctx) - tut = analysistest.target_under_test(env) - action = tut.actions[1] - assert_action_mnemonic(env, action, "Rustc") - assert_argv_contains(env, action, ctx.bin_dir.path + "/test/unit/location_expansion/mylibrary.rs") - expected = "@${pwd}/" + ctx.bin_dir.path + "/test/unit/location_expansion/generated_flag.data" + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] + assert_argv_contains(env, action, analysistest.target_bin_dir_path(env) + "/test/unit/location_expansion/mylibrary.rs") + expected = "@${pwd}/" + analysistest.target_bin_dir_path(env) + "/test/unit/location_expansion/generated_flag.data" assert_argv_contains(env, action, expected) return analysistest.end(env) diff --git a/test/unit/lto/lto_test_suite.bzl b/test/unit/lto/lto_test_suite.bzl index 8ccf47da18..4b5080cf3b 100644 --- a/test/unit/lto/lto_test_suite.bzl +++ b/test/unit/lto/lto_test_suite.bzl @@ -5,7 +5,6 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_library", "rust_proc_macro") load( "//test/unit:common.bzl", - "assert_action_mnemonic", "assert_argv_contains", "assert_argv_contains_not", "assert_argv_contains_prefix_not", @@ -13,10 +12,8 @@ load( def _lto_test_impl(ctx, lto_setting, embed_bitcode, linker_plugin): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] # Check if LTO is enabled. if lto_setting: diff --git a/test/unit/native_deps/native_deps_test.bzl b/test/unit/native_deps/native_deps_test.bzl index ab97be6598..f192d75ff4 100644 --- a/test/unit/native_deps/native_deps_test.bzl +++ b/test/unit/native_deps/native_deps_test.bzl @@ -16,13 +16,6 @@ load( def _get_toolchain(ctx): return ctx.attr._toolchain[platform_common.ToolchainInfo] -def _get_darwin_component(arg): - # path/to/darwin_x86_64-fastbuild-fastbuild/package -> darwin_x86_64-fastbuild - darwin_component = [x for x in arg.split("/") if x.startswith("darwin")][0] - - # darwin_x86_64-fastbuild -> darwin - return darwin_component.split("-")[0] - def _rlib_has_no_native_libs_test_impl(ctx): env = analysistest.begin(ctx) tut = analysistest.target_under_test(env) @@ -138,15 +131,14 @@ def _bin_has_native_dep_and_alwayslink_test_impl(ctx): action = tut.actions[0] toolchain = _get_toolchain(ctx) - compilation_mode = ctx.var["COMPILATION_MODE"] + bin_dir = analysistest.target_bin_dir_path(env) workspace_prefix = _get_workspace_prefix(ctx) link_args = _extract_linker_args(action.argv) if toolchain.target_os in ["macos", "darwin"]: - darwin_component = _get_darwin_component(link_args[-1]) want = [ "-lstatic=native_dep", "-lnative_dep", - "-Wl,-force_load,bazel-out/{}-{}/bin/{}test/unit/native_deps/libalwayslink.lo".format(darwin_component, compilation_mode, workspace_prefix), + "-Wl,-force_load,{}/{}test/unit/native_deps/libalwayslink.lo".format(bin_dir, workspace_prefix), ] assert_list_contains_adjacent_elements(env, link_args, want) elif toolchain.target_os == "windows": @@ -154,21 +146,21 @@ def _bin_has_native_dep_and_alwayslink_test_impl(ctx): want = [ "-lstatic=native_dep", "native_dep.lib", - "/WHOLEARCHIVE:bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/alwayslink.lo.lib".format(compilation_mode, workspace_prefix), + "/WHOLEARCHIVE:{}/{}test/unit/native_deps/alwayslink.lo.lib".format(bin_dir, workspace_prefix), ] else: want = [ "-lstatic=native_dep", "native_dep.lib", "-Wl,--whole-archive", - "bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/alwayslink.lo.lib".format(compilation_mode, workspace_prefix), + "{}/{}test/unit/native_deps/alwayslink.lo.lib".format(bin_dir, workspace_prefix), "-Wl,--no-whole-archive", ] elif toolchain.target_arch == "s390x": want = [ "-lstatic=native_dep", "link-arg=-Wl,--whole-archive", - "link-arg=bazel-out/s390x-{}/bin/{}test/unit/native_deps/libalwayslink.lo".format(compilation_mode, workspace_prefix), + "link-arg={}/{}test/unit/native_deps/libalwayslink.lo".format(bin_dir, workspace_prefix), "link-arg=-Wl,--no-whole-archive", ] else: @@ -176,7 +168,7 @@ def _bin_has_native_dep_and_alwayslink_test_impl(ctx): "-lstatic=native_dep", "-lnative_dep", "-Wl,--whole-archive", - "bazel-out/k8-{}/bin/{}test/unit/native_deps/libalwayslink.lo".format(compilation_mode, workspace_prefix), + "{}/{}test/unit/native_deps/libalwayslink.lo".format(bin_dir, workspace_prefix), "-Wl,--no-whole-archive", ] assert_list_contains_adjacent_elements(env, link_args, want) @@ -193,35 +185,35 @@ def _cdylib_has_native_dep_and_alwayslink_test_impl(ctx): toolchain = _get_toolchain(ctx) compilation_mode = ctx.var["COMPILATION_MODE"] + bin_dir = analysistest.target_bin_dir_path(env) workspace_prefix = _get_workspace_prefix(ctx) pic_suffix = _get_pic_suffix(ctx, compilation_mode) if toolchain.target_os in ["macos", "darwin"]: - darwin_component = _get_darwin_component(linker_args[-1]) want = [ "-lstatic=native_dep{}".format(pic_suffix), "-lnative_dep{}".format(pic_suffix), - "-Wl,-force_load,bazel-out/{}-{}/bin/{}test/unit/native_deps/libalwayslink{}.lo".format(darwin_component, compilation_mode, workspace_prefix, pic_suffix), + "-Wl,-force_load,{}/{}test/unit/native_deps/libalwayslink{}.lo".format(bin_dir, workspace_prefix, pic_suffix), ] elif toolchain.target_os == "windows": if toolchain.target_triple.abi == "msvc": want = [ "-lstatic=native_dep", "native_dep.lib", - "/WHOLEARCHIVE:bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/alwayslink.lo.lib".format(compilation_mode, workspace_prefix), + "/WHOLEARCHIVE:{}/{}test/unit/native_deps/alwayslink.lo.lib".format(bin_dir, workspace_prefix), ] else: want = [ "-lstatic=native_dep", "native_dep.lib", "-Wl,--whole-archive", - "bazel-out/x64_windows-{}/bin/{}test/unit/native_deps/alwayslink.lo.lib".format(compilation_mode, workspace_prefix), + "{}/{}test/unit/native_deps/alwayslink.lo.lib".format(bin_dir, workspace_prefix), "-Wl,--no-whole-archive", ] elif toolchain.target_arch == "s390x": want = [ "-lstatic=native_dep{}".format(pic_suffix), "link-arg=-Wl,--whole-archive", - "link-arg=bazel-out/s390x-{}/bin/{}test/unit/native_deps/libalwayslink{}.lo".format(compilation_mode, workspace_prefix, pic_suffix), + "link-arg={}/{}test/unit/native_deps/libalwayslink{}.lo".format(bin_dir, workspace_prefix, pic_suffix), "link-arg=-Wl,--no-whole-archive", ] else: @@ -229,7 +221,7 @@ def _cdylib_has_native_dep_and_alwayslink_test_impl(ctx): "-lstatic=native_dep{}".format(pic_suffix), "-lnative_dep{}".format(pic_suffix), "-Wl,--whole-archive", - "bazel-out/k8-{}/bin/{}test/unit/native_deps/libalwayslink{}.lo".format(compilation_mode, workspace_prefix, pic_suffix), + "{}/{}test/unit/native_deps/libalwayslink{}.lo".format(bin_dir, workspace_prefix, pic_suffix), "-Wl,--no-whole-archive", ] assert_list_contains_adjacent_elements(env, linker_args, want) diff --git a/test/unit/opt_level/opt_level_test_suite.bzl b/test/unit/opt_level/opt_level_test_suite.bzl index 9003a67200..80e071ad53 100644 --- a/test/unit/opt_level/opt_level_test_suite.bzl +++ b/test/unit/opt_level/opt_level_test_suite.bzl @@ -5,16 +5,13 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary") load( "//test/unit:common.bzl", - "assert_action_mnemonic", "assert_argv_contains", ) def _opt_level_test_impl(ctx, expected_level): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] assert_argv_contains(env, action, "--codegen=opt-level={}".format(expected_level)) return analysistest.end(env) diff --git a/test/unit/rust_binary_name/rust_binary_name_suite.bzl b/test/unit/rust_binary_name/rust_binary_name_suite.bzl index 61f8df3429..e62a5db4cf 100644 --- a/test/unit/rust_binary_name/rust_binary_name_suite.bzl +++ b/test/unit/rust_binary_name/rust_binary_name_suite.bzl @@ -9,9 +9,8 @@ def _rust_binary_binary_name_test_impl(ctx): expected_basename = ctx.attr.expected_binary_name env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] output = action.outputs.to_list()[0] filename = paths.split_extension(output.basename)[0] diff --git a/test/unit/stamp/stamp_test.bzl b/test/unit/stamp/stamp_test.bzl index 871808d38d..da5c67133e 100644 --- a/test/unit/stamp/stamp_test.bzl +++ b/test/unit/stamp/stamp_test.bzl @@ -4,7 +4,6 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest") load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_library", "rust_test") load( "//test/unit:common.bzl", - "assert_action_mnemonic", "assert_argv_contains", "assert_argv_contains_not", ) @@ -30,8 +29,7 @@ def _stamp_build_flag_test_impl(ctx, flag_value): env = analysistest.begin(ctx) target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] is_test = target[rust_common.crate_info].is_test is_bin = target[rust_common.crate_info].type == "bin" @@ -130,10 +128,8 @@ def _build_flag_tests(): def _attribute_stamp_test_impl(ctx, attribute_value, build_flag_value): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] if attribute_value == 1: _assert_stamped(env, action) @@ -279,10 +275,8 @@ def _stamp_attribute_tests(): def _process_wrapper_with_stamp_test_impl(ctx): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] _assert_not_stamped(env, action) diff --git a/test/unit/strip_level/strip_level_test_suite.bzl b/test/unit/strip_level/strip_level_test_suite.bzl index a4b6b30171..1699e4d9a5 100644 --- a/test/unit/strip_level/strip_level_test_suite.bzl +++ b/test/unit/strip_level/strip_level_test_suite.bzl @@ -5,16 +5,13 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary") load( "//test/unit:common.bzl", - "assert_action_mnemonic", "assert_argv_contains", ) def _strip_level_test_impl(ctx, expected_level): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - assert_action_mnemonic(env, action, "Rustc") + action = [a for a in analysistest.target_actions(env) if a.mnemonic == "Rustc"][0] assert_argv_contains(env, action, "--codegen=strip={}".format(expected_level)) return analysistest.end(env) diff --git a/test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl b/test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl index f6dc8ba163..99b564fff3 100644 --- a/test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl +++ b/test/unit/toolchain_make_variables/toolchain_make_variables_test.bzl @@ -2,7 +2,7 @@ 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") +load("//test/unit:common.bzl", "assert_env_value") _RUST_TOOLCHAIN_ENV = { "ENV_VAR_CARGO": "$(CARGO)", @@ -16,25 +16,59 @@ _RUSTFMT_TOOLCHAIN_ENV = { "ENV_VAR_RUSTFMT": "$(RUSTFMT)", } +_RUST_TOOLCHAIN_TYPE = str(Label("@rules_rust//rust:toolchain_type")) +_RUSTFMT_TOOLCHAIN_TYPE = str(Label("@rules_rust//rust/rustfmt:toolchain_type")) +_CURRENT_RUST_TOOLCHAIN = Label("//rust/toolchain:current_rust_toolchain") +_CURRENT_RUSTFMT_TOOLCHAIN = Label("//rust/toolchain:current_rustfmt_toolchain") + +def _retrieve_toolchain_aspect_impl(_, ctx, toolchain_type): + if hasattr(ctx.rule, "toolchains") and toolchain_type in ctx.rule.toolchains: + return ctx.rule.toolchains[toolchain_type] + if toolchain_type == _RUST_TOOLCHAIN_TYPE: + return ctx.attr._current_rust_toolchain[platform_common.ToolchainInfo] + if toolchain_type == _RUSTFMT_TOOLCHAIN_TYPE: + return ctx.attr._current_rustfmt_toolchain[platform_common.ToolchainInfo] + return [] + +_retrieve_rust_toolchain = aspect( + implementation = lambda target, ctx: _retrieve_toolchain_aspect_impl( + target, + ctx, + toolchain_type = _RUST_TOOLCHAIN_TYPE, + ), + attrs = { + "_current_rust_toolchain": attr.label( + default = _CURRENT_RUST_TOOLCHAIN, + ), + }, + provides = [platform_common.ToolchainInfo], +) + +_retrieve_rustfmt_toolchain = aspect( + implementation = lambda target, ctx: _retrieve_toolchain_aspect_impl( + target, + ctx, + toolchain_type = _RUSTFMT_TOOLCHAIN_TYPE, + ), + attrs = { + "_current_rustfmt_toolchain": attr.label( + default = _CURRENT_RUSTFMT_TOOLCHAIN, + ), + }, + provides = [platform_common.ToolchainInfo], +) + def _rust_toolchain_make_variable_expansion_test_common_impl(ctx, mnemonic): env = analysistest.begin(ctx) - target = analysistest.target_under_test(env) - action = target.actions[0] - - assert_action_mnemonic( - env = env, - action = action, - mnemonic = mnemonic, - ) + action = [a for a in analysistest.target_actions(env) if a.mnemonic == mnemonic][0] + toolchain = analysistest.target_under_test(env)[platform_common.ToolchainInfo] if mnemonic in ["RustFmtToolchainConsumer", "CurrentRustFmtToolchainConsumer"]: - toolchain = ctx.attr._current_rustfmt_toolchain[platform_common.ToolchainInfo] env_vars = _RUSTFMT_TOOLCHAIN_ENV expected_values = { "ENV_VAR_RUSTFMT": toolchain.rustfmt.path, } else: - toolchain = ctx.attr._current_rust_toolchain[platform_common.ToolchainInfo] env_vars = _RUST_TOOLCHAIN_ENV expected_values = { "ENV_VAR_CARGO": toolchain.cargo.path, @@ -57,23 +91,13 @@ def _rust_toolchain_make_variable_expansion_test_common_impl(ctx, mnemonic): def rust_toolchain_make_toolchain_make_variable_test(impl): return analysistest.make( impl = impl, - attrs = { - "_current_rust_toolchain": attr.label( - doc = "The currently registered rust toolchain", - default = Label("//rust/toolchain:current_rust_toolchain"), - ), - }, + extra_target_under_test_aspects = [_retrieve_rust_toolchain], ) def rustfmt_toolchain_make_toolchain_make_variable_test(impl): return analysistest.make( impl = impl, - attrs = { - "_current_rustfmt_toolchain": attr.label( - doc = "The currently registered rustfmt toolchain", - default = Label("//rust/toolchain:current_rustfmt_toolchain"), - ), - }, + extra_target_under_test_aspects = [_retrieve_rustfmt_toolchain], ) def _rustc_env_variable_expansion_test_impl(ctx): @@ -158,7 +182,7 @@ rust_toolchain_consumer = rule( ), }, toolchains = [ - "@rules_rust//rust:toolchain_type", + _RUST_TOOLCHAIN_TYPE, ], ) @@ -201,7 +225,7 @@ rustfmt_toolchain_consumer = rule( ), }, toolchains = [ - "@rules_rust//rust/rustfmt:toolchain_type", + _RUSTFMT_TOOLCHAIN_TYPE, ], ) @@ -223,9 +247,6 @@ current_rustfmt_toolchain_consumer = rule( mandatory = True, ), }, - toolchains = [ - "@rules_rust//rust/rustfmt:toolchain_type", - ], ) def _define_targets(): @@ -265,7 +286,7 @@ def _define_targets(): current_rust_toolchain_consumer( name = "current_rust_toolchain_consumer", env = _RUST_TOOLCHAIN_ENV, - toolchains = ["//rust/toolchain:current_rust_toolchain"], + toolchains = [str(_CURRENT_RUST_TOOLCHAIN)], writer = ":binary", ) @@ -278,7 +299,7 @@ def _define_targets(): current_rustfmt_toolchain_consumer( name = "current_rustfmt_toolchain_consumer", env = _RUSTFMT_TOOLCHAIN_ENV, - toolchains = ["//rust/toolchain:current_rustfmt_toolchain"], + toolchains = [str(_CURRENT_RUSTFMT_TOOLCHAIN)], writer = ":binary", )