From b0684bb05e1e9f4ff899b13bac1f652e56398428 Mon Sep 17 00:00:00 2001 From: Brian Granaghan Date: Fri, 19 Jan 2024 23:59:20 +0000 Subject: [PATCH] Add extra_rustc_flags_for_crate_types. This allows extra rustc flags that will only apply to specific library types to be set by the toolchain. Cross language LTO needs '-C linker-plugin-lto' on libraries, how passing this flag to rust_binary generated bloat. Adding this attribute resolves this issue. Change-Id: Iba725fab1b1941e9586ff97cd71ec3bc1dfc1523 --- rust/private/rustc.bzl | 3 ++ rust/toolchain.bzl | 4 ++ test/toolchain/main.rs | 1 + test/toolchain/toolchain_test.bzl | 74 ++++++++++++++++++++++++++++--- 4 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 test/toolchain/main.rs diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index e101223065..f6f632dba6 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1070,6 +1070,9 @@ def construct_arguments( if toolchain._rename_first_party_crates: env["RULES_RUST_THIRD_PARTY_DIR"] = toolchain._third_party_dir + if crate_info.type in toolchain.extra_rustc_flags_for_crate_types.keys(): + rustc_flags.add_all(toolchain.extra_rustc_flags_for_crate_types[crate_info.type]) + if is_exec_configuration(ctx): rustc_flags.add_all(toolchain.extra_exec_rustc_flags) else: diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 1d268ec0a8..36c42b7a67 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -650,6 +650,7 @@ def _rust_toolchain_impl(ctx): staticlib_ext = ctx.attr.staticlib_ext, stdlib_linkflags = stdlib_linkflags_cc_info, extra_rustc_flags = ctx.attr.extra_rustc_flags, + extra_rustc_flags_for_crate_types = ctx.attr.extra_rustc_flags_for_crate_types, extra_exec_rustc_flags = ctx.attr.extra_exec_rustc_flags, per_crate_rustc_flags = ctx.attr.per_crate_rustc_flags, sysroot = sysroot_path, @@ -747,6 +748,9 @@ rust_toolchain = rule( "extra_rustc_flags": attr.string_list( doc = "Extra flags to pass to rustc in non-exec configuration", ), + "extra_rustc_flags_for_crate_types": attr.string_list_dict( + doc = "Extra flags to pass to rustc based on crate type", + ), "global_allocator_library": attr.label( doc = "Target that provides allocator functions for when a global allocator is present.", default = "@rules_rust//ffi/cc/global_allocator_library", diff --git a/test/toolchain/main.rs b/test/toolchain/main.rs new file mode 100644 index 0000000000..f328e4d9d0 --- /dev/null +++ b/test/toolchain/main.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/test/toolchain/toolchain_test.bzl b/test/toolchain/toolchain_test.bzl index 5c74fae6d1..7180fab914 100644 --- a/test/toolchain/toolchain_test.bzl +++ b/test/toolchain/toolchain_test.bzl @@ -2,18 +2,20 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@bazel_skylib//rules:write_file.bzl", "write_file") -load("//rust:defs.bzl", "rust_library") +load("//rust:defs.bzl", "rust_library", "rust_shared_library") load("//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain") EXEC_TOOLCHAIN_FLAG = "missing" TOOLCHAIN_FLAG = "before" CONFIG_FLAG = "after" +CRATE_FLAGS = {"cdylib": ["cdylib_flag"], "rlib": ["rlib_flag"]} -def _toolchain_adds_rustc_flags_impl(ctx): +def _toolchain_adds_rustc_flags_impl(ctx, crate_type): """ Tests adding extra_rustc_flags on the toolchain, asserts that: - extra_rustc_flags added by the toolchain are applied BEFORE flags added by a config on the commandline - The exec flags from the toolchain don't go on the commandline for a non-exec target + - crate type rustc flags are added """ env = analysistest.begin(ctx) target = analysistest.target_under_test(env) @@ -30,6 +32,27 @@ def _toolchain_adds_rustc_flags_impl(ctx): ), ) + asserts.true( + env, + action.argv[-3] == CRATE_FLAGS[crate_type][0], + "Unexpected rustc flags: {}\nShould have contained: {}".format( + action.argv, + CRATE_FLAGS["rlib"], + ), + ) + + for type in CRATE_FLAGS.keys(): + if type == crate_type: + continue + asserts.false( + env, + CRATE_FLAGS[type][0] in action.argv, + "Unexpected rustc flags: {}\nShould not contain: {}".format( + action.argv, + CRATE_FLAGS[type], + ), + ) + asserts.true( env, EXEC_TOOLCHAIN_FLAG not in action.argv, @@ -48,8 +71,22 @@ def _toolchain_adds_rustc_flags_impl(ctx): return analysistest.end(env) -toolchain_adds_rustc_flags_test = analysistest.make( - _toolchain_adds_rustc_flags_impl, +def _toolchain_adds_rustc_flags_lib_impl(ctx): + return _toolchain_adds_rustc_flags_impl(ctx, "rlib") + +def _toolchain_adds_rustc_flags_shared_lib_impl(ctx): + return _toolchain_adds_rustc_flags_impl(ctx, "cdylib") + +toolchain_adds_rustc_flags_lib_test = analysistest.make( + _toolchain_adds_rustc_flags_lib_impl, + config_settings = { + str(Label("//:extra_rustc_flags")): [CONFIG_FLAG], + str(Label("//rust/settings:experimental_toolchain_generated_sysroot")): True, + }, +) + +toolchain_adds_rustc_flags_bin_test = analysistest.make( + _toolchain_adds_rustc_flags_shared_lib_impl, config_settings = { str(Label("//:extra_rustc_flags")): [CONFIG_FLAG], str(Label("//rust/settings:experimental_toolchain_generated_sysroot")): True, @@ -105,6 +142,12 @@ def _define_targets(): edition = "2021", ) + rust_shared_library( + name = "shared_lib", + srcs = ["lib.rs"], + edition = "2021", + ) + native.filegroup( name = "stdlib_srcs", srcs = ["config.txt"], @@ -139,6 +182,7 @@ def _define_targets(): stdlib_linkflags = [], extra_rustc_flags = [TOOLCHAIN_FLAG], extra_exec_rustc_flags = [EXEC_TOOLCHAIN_FLAG], + extra_rustc_flags_for_crate_types = CRATE_FLAGS, visibility = ["//visibility:public"], ) @@ -153,6 +197,11 @@ def _define_targets(): dep = ":lib", ) + extra_toolchain_wrapper( + name = "shared_lib_with_extra_toolchain", + dep = ":shared_lib", + ) + def _rust_stdlib_filegroup_provides_runfiles_test_impl(ctx): env = analysistest.begin(ctx) target = analysistest.target_under_test(env) @@ -166,13 +215,23 @@ rust_stdlib_filegroup_provides_runfiles_test = analysistest.make( ) def toolchain_test_suite(name): + """ Instantiates tests for rust toolchains. + + Args: + name: a name for the test suite + """ _define_targets() - toolchain_adds_rustc_flags_test( - name = "toolchain_adds_rustc_flags_test", + toolchain_adds_rustc_flags_lib_test( + name = "toolchain_adds_rustc_flags_lib_test", target_under_test = ":lib_with_extra_toolchain", ) + toolchain_adds_rustc_flags_bin_test( + name = "toolchain_adds_rustc_flags_shared_lib_test", + target_under_test = ":shared_lib_with_extra_toolchain", + ) + rust_stdlib_filegroup_provides_runfiles_test( name = "rust_stdlib_filegroup_provides_runfiles_test", target_under_test = ":std_libs", @@ -181,7 +240,8 @@ def toolchain_test_suite(name): native.test_suite( name = name, tests = [ - ":toolchain_adds_rustc_flags_test", + ":toolchain_adds_rustc_flags_lib_test", + ":toolchain_adds_rustc_flags_bin_test", ":rust_stdlib_filegroup_provides_runfiles_test", ], )