Add extra_rustc_flags_for_crate_types. (#2431)
This allows extra rustc flags that will only apply to library targets 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
---------
Co-authored-by: UebelAndre <github@uebelandre.com>
diff --git a/docs/flatten.md b/docs/flatten.md
index 7fa9bfc..24c6baa 100644
--- a/docs/flatten.md
+++ b/docs/flatten.md
@@ -1178,9 +1178,9 @@
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_link_std_dylib">experimental_link_std_dylib</a>,
<a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>, <a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>,
- <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>,
- <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>,
- <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
+ <a href="#rust_toolchain-extra_rustc_flags_for_crate_types">extra_rustc_flags_for_crate_types</a>, <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>,
+ <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>,
+ <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>
Declares a Rust toolchain for use.
@@ -1246,6 +1246,7 @@
| <a id="rust_toolchain-experimental_use_cc_common_link"></a>experimental_use_cc_common_link | Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>//rust/settings:experimental_use_cc_common_link</code> |
| <a id="rust_toolchain-extra_exec_rustc_flags"></a>extra_exec_rustc_flags | Extra flags to pass to rustc in exec configuration | List of strings | optional | <code>[]</code> |
| <a id="rust_toolchain-extra_rustc_flags"></a>extra_rustc_flags | Extra flags to pass to rustc in non-exec configuration | List of strings | optional | <code>[]</code> |
+| <a id="rust_toolchain-extra_rustc_flags_for_crate_types"></a>extra_rustc_flags_for_crate_types | Extra flags to pass to rustc based on crate type | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> List of strings</a> | optional | <code>{}</code> |
| <a id="rust_toolchain-global_allocator_library"></a>global_allocator_library | Target that provides allocator functions for when a global allocator is present. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>@rules_rust//ffi/cc/global_allocator_library</code> |
| <a id="rust_toolchain-llvm_cov"></a>llvm_cov | The location of the <code>llvm-cov</code> binary. Can be a direct source or a filegroup containing one item. If None, rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
| <a id="rust_toolchain-llvm_profdata"></a>llvm_profdata | The location of the <code>llvm-profdata</code> binary. Can be a direct source or a filegroup containing one item. If <code>llvm_cov</code> is None, this can be None as well and rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
diff --git a/docs/rust_repositories.md b/docs/rust_repositories.md
index 0175c53..443b07a 100644
--- a/docs/rust_repositories.md
+++ b/docs/rust_repositories.md
@@ -39,9 +39,9 @@
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_link_std_dylib">experimental_link_std_dylib</a>,
<a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>, <a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>,
- <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>,
- <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>,
- <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
+ <a href="#rust_toolchain-extra_rustc_flags_for_crate_types">extra_rustc_flags_for_crate_types</a>, <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>,
+ <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>,
+ <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>
Declares a Rust toolchain for use.
@@ -107,6 +107,7 @@
| <a id="rust_toolchain-experimental_use_cc_common_link"></a>experimental_use_cc_common_link | Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>//rust/settings:experimental_use_cc_common_link</code> |
| <a id="rust_toolchain-extra_exec_rustc_flags"></a>extra_exec_rustc_flags | Extra flags to pass to rustc in exec configuration | List of strings | optional | <code>[]</code> |
| <a id="rust_toolchain-extra_rustc_flags"></a>extra_rustc_flags | Extra flags to pass to rustc in non-exec configuration | List of strings | optional | <code>[]</code> |
+| <a id="rust_toolchain-extra_rustc_flags_for_crate_types"></a>extra_rustc_flags_for_crate_types | Extra flags to pass to rustc based on crate type | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> List of strings</a> | optional | <code>{}</code> |
| <a id="rust_toolchain-global_allocator_library"></a>global_allocator_library | Target that provides allocator functions for when a global allocator is present. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>@rules_rust//ffi/cc/global_allocator_library</code> |
| <a id="rust_toolchain-llvm_cov"></a>llvm_cov | The location of the <code>llvm-cov</code> binary. Can be a direct source or a filegroup containing one item. If None, rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
| <a id="rust_toolchain-llvm_profdata"></a>llvm_profdata | The location of the <code>llvm-profdata</code> binary. Can be a direct source or a filegroup containing one item. If <code>llvm_cov</code> is None, this can be None as well and rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
index e101223..f6f632d 100644
--- a/rust/private/rustc.bzl
+++ b/rust/private/rustc.bzl
@@ -1070,6 +1070,9 @@
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 1d268ec..36c42b7 100644
--- a/rust/toolchain.bzl
+++ b/rust/toolchain.bzl
@@ -650,6 +650,7 @@
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 @@
"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 0000000..f328e4d
--- /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 5c74fae..b61a351 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)
@@ -32,6 +34,27 @@
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,
"Found exec toolchain flag ({}) in rustc flags: {}".format(EXEC_TOOLCHAIN_FLAG, action.argv),
)
@@ -48,8 +71,22 @@
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_shared_lib_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 @@
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 @@
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 @@
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 @@
)
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_shared_lib_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 @@
native.test_suite(
name = name,
tests = [
- ":toolchain_adds_rustc_flags_test",
+ ":toolchain_adds_rustc_flags_lib_test",
+ ":toolchain_adds_rustc_flags_shared_lib_test",
":rust_stdlib_filegroup_provides_runfiles_test",
],
)