Skip to content

Commit bd1bd10

Browse files
authored
feat: Strip debug info from opt builds (#2513)
Attempts to follow the cargo proposal linked below to remove debug info for release builds. Furthermore this should uphold the expected behavior of bazel for cc builds which automatically strips debug symbols for optimized builds. rust-lang/cargo#4122 (comment)
1 parent fe2bc68 commit bd1bd10

File tree

6 files changed

+124
-5
lines changed

6 files changed

+124
-5
lines changed

docs/flatten.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,7 @@ rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain
11801180
<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>,
11811181
<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>,
11821182
<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>,
1183-
<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>)
1183+
<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-strip_level">strip_level</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
11841184
</pre>
11851185

11861186
Declares a Rust toolchain for use.
@@ -1260,6 +1260,7 @@ See `@rules_rust//rust:repositories.bzl` for examples of defining the `@rust_cpu
12601260
| <a id="rust_toolchain-rustfmt"></a>rustfmt | **Deprecated**: Instead see [rustfmt_toolchain](#rustfmt_toolchain) | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
12611261
| <a id="rust_toolchain-staticlib_ext"></a>staticlib_ext | The extension for static libraries created from rustc. | String | required | |
12621262
| <a id="rust_toolchain-stdlib_linkflags"></a>stdlib_linkflags | Additional linker flags to use when Rust standard library is linked by a C++ linker (rustc will deal with these automatically). Subject to location expansion with respect to the srcs of the <code>rust_std</code> attribute. | List of strings | required | |
1263+
| <a id="rust_toolchain-strip_level"></a>strip_level | Rustc strip levels. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{"dbg": "none", "fastbuild": "none", "opt": "debuginfo"}</code> |
12631264
| <a id="rust_toolchain-target_json"></a>target_json | Override the target_triple with a custom target specification. For more details see: https://doc.rust-lang.org/rustc/targets/custom.html | String | optional | <code>""</code> |
12641265
| <a id="rust_toolchain-target_triple"></a>target_triple | The platform triple for the toolchains target environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | optional | <code>""</code> |
12651266

docs/rust_repositories.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain
4141
<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>,
4242
<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>,
4343
<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>,
44-
<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>)
44+
<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-strip_level">strip_level</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
4545
</pre>
4646

4747
Declares a Rust toolchain for use.
@@ -121,6 +121,7 @@ See `@rules_rust//rust:repositories.bzl` for examples of defining the `@rust_cpu
121121
| <a id="rust_toolchain-rustfmt"></a>rustfmt | **Deprecated**: Instead see [rustfmt_toolchain](#rustfmt_toolchain) | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
122122
| <a id="rust_toolchain-staticlib_ext"></a>staticlib_ext | The extension for static libraries created from rustc. | String | required | |
123123
| <a id="rust_toolchain-stdlib_linkflags"></a>stdlib_linkflags | Additional linker flags to use when Rust standard library is linked by a C++ linker (rustc will deal with these automatically). Subject to location expansion with respect to the srcs of the <code>rust_std</code> attribute. | List of strings | required | |
124+
| <a id="rust_toolchain-strip_level"></a>strip_level | Rustc strip levels. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{"dbg": "none", "fastbuild": "none", "opt": "debuginfo"}</code> |
124125
| <a id="rust_toolchain-target_json"></a>target_json | Override the target_triple with a custom target specification. For more details see: https://doc.rust-lang.org/rustc/targets/custom.html | String | optional | <code>""</code> |
125126
| <a id="rust_toolchain-target_triple"></a>target_triple | The platform triple for the toolchains target environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | optional | <code>""</code> |
126127

rust/private/rustc.bzl

+2
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,8 @@ def construct_arguments(
959959
compilation_mode = get_compilation_mode_opts(ctx, toolchain)
960960
rustc_flags.add(compilation_mode.opt_level, format = "--codegen=opt-level=%s")
961961
rustc_flags.add(compilation_mode.debug_info, format = "--codegen=debuginfo=%s")
962+
if toolchain.target_os != "windows":
963+
rustc_flags.add(compilation_mode.strip_level, format = "--codegen=strip=%s")
962964

963965
# For determinism to help with build distribution and such
964966
if remap_path_prefix != None:

rust/toolchain.bzl

+13-3
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,13 @@ def _rust_toolchain_impl(ctx):
490490
list: A list containing the target's toolchain Provider info
491491
"""
492492
compilation_mode_opts = {}
493-
for k, v in ctx.attr.opt_level.items():
493+
for k, opt_level in ctx.attr.opt_level.items():
494494
if not k in ctx.attr.debug_info:
495495
fail("Compilation mode {} is not defined in debug_info but is defined opt_level".format(k))
496-
compilation_mode_opts[k] = struct(debug_info = ctx.attr.debug_info[k], opt_level = v)
497-
for k, v in ctx.attr.debug_info.items():
496+
if not k in ctx.attr.strip_level:
497+
fail("Compilation mode {} is not defined in strip_level but is defined opt_level".format(k))
498+
compilation_mode_opts[k] = struct(debug_info = ctx.attr.debug_info[k], opt_level = opt_level, strip_level = ctx.attr.strip_level[k])
499+
for k in ctx.attr.debug_info.keys():
498500
if not k in ctx.attr.opt_level:
499501
fail("Compilation mode {} is not defined in opt_level but is defined debug_info".format(k))
500502

@@ -817,6 +819,14 @@ rust_toolchain = rule(
817819
),
818820
mandatory = True,
819821
),
822+
"strip_level": attr.string_dict(
823+
doc = "Rustc strip levels.",
824+
default = {
825+
"dbg": "none",
826+
"fastbuild": "none",
827+
"opt": "debuginfo",
828+
},
829+
),
820830
"target_json": attr.string(
821831
doc = ("Override the target_triple with a custom target specification. " +
822832
"For more details see: https://doc.rust-lang.org/rustc/targets/custom.html"),

test/unit/strip_level/BUILD.bazel

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
load(":strip_level_test_suite.bzl", "strip_level_test_suite")
2+
3+
strip_level_test_suite(
4+
name = "strip_level_test_suite",
5+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""Starlark tests for `rust_toolchain.strip_level`"""
2+
3+
load("@bazel_skylib//lib:unittest.bzl", "analysistest")
4+
load("@bazel_skylib//rules:write_file.bzl", "write_file")
5+
load("//rust:defs.bzl", "rust_binary")
6+
load(
7+
"//test/unit:common.bzl",
8+
"assert_action_mnemonic",
9+
"assert_argv_contains",
10+
)
11+
12+
def _strip_level_test_impl(ctx, expected_level):
13+
env = analysistest.begin(ctx)
14+
target = analysistest.target_under_test(env)
15+
16+
action = target.actions[0]
17+
assert_action_mnemonic(env, action, "Rustc")
18+
19+
assert_argv_contains(env, action, "--codegen=strip={}".format(expected_level))
20+
return analysistest.end(env)
21+
22+
def _strip_level_for_dbg_test_impl(ctx):
23+
return _strip_level_test_impl(ctx, "none")
24+
25+
_strip_level_for_dbg_test = analysistest.make(
26+
_strip_level_for_dbg_test_impl,
27+
config_settings = {
28+
"//command_line_option:compilation_mode": "dbg",
29+
},
30+
)
31+
32+
def _strip_level_for_fastbuild_test_impl(ctx):
33+
return _strip_level_test_impl(ctx, "none")
34+
35+
_strip_level_for_fastbuild_test = analysistest.make(
36+
_strip_level_for_fastbuild_test_impl,
37+
config_settings = {
38+
"//command_line_option:compilation_mode": "fastbuild",
39+
},
40+
)
41+
42+
def _strip_level_for_opt_test_impl(ctx):
43+
return _strip_level_test_impl(ctx, "debuginfo")
44+
45+
_strip_level_for_opt_test = analysistest.make(
46+
_strip_level_for_opt_test_impl,
47+
config_settings = {
48+
"//command_line_option:compilation_mode": "opt",
49+
},
50+
)
51+
52+
def strip_level_test_suite(name):
53+
"""Entry-point macro called from the BUILD file.
54+
55+
Args:
56+
name (str): The name of the test suite.
57+
"""
58+
write_file(
59+
name = "bin_main",
60+
out = "main.rs",
61+
content = [
62+
"fn main() {}",
63+
"",
64+
],
65+
)
66+
67+
rust_binary(
68+
name = "bin",
69+
srcs = [":main.rs"],
70+
edition = "2021",
71+
target_compatible_with = [
72+
"@platforms//os:linux",
73+
"@platforms//os:macos",
74+
"@platforms//os:none",
75+
],
76+
)
77+
78+
_strip_level_for_dbg_test(
79+
name = "strip_level_for_dbg_test",
80+
target_under_test = ":bin",
81+
)
82+
83+
_strip_level_for_fastbuild_test(
84+
name = "strip_level_for_fastbuild_test",
85+
target_under_test = ":bin",
86+
)
87+
88+
_strip_level_for_opt_test(
89+
name = "strip_level_for_opt_test",
90+
target_under_test = ":bin",
91+
)
92+
93+
native.test_suite(
94+
name = name,
95+
tests = [
96+
":strip_level_for_dbg_test",
97+
":strip_level_for_fastbuild_test",
98+
":strip_level_for_opt_test",
99+
],
100+
)

0 commit comments

Comments
 (0)