Skip to content

Commit a862cde

Browse files
UebelAndrehlopko
andauthored
Added rust_stdlib_filegroup rule, a helper for creating toolchains (#802)
* Added `rust_stdlib_filegroup` rule, a helper for creating toolchains * Updated error messaging. * Rewrite the error message * Updated code to reflect messaging * Plugged in docs * Regenerate documentation Co-authored-by: Marcel Hlopko <marcel@hlopko.com>
1 parent f4cbea5 commit a862cde

File tree

9 files changed

+154
-38
lines changed

9 files changed

+154
-38
lines changed

docs/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ PAGES = dict([
113113
"rust_toolchain",
114114
"rust_toolchain_repository",
115115
"rust_toolchain_repository_proxy",
116+
"rust_stdlib_filegroup",
116117
],
117118
),
118119
page(

docs/flatten.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* [rust_repository_set](#rust_repository_set)
2626
* [rust_shared_library](#rust_shared_library)
2727
* [rust_static_library](#rust_static_library)
28+
* [rust_stdlib_filegroup](#rust_stdlib_filegroup)
2829
* [rust_test](#rust_test)
2930
* [rust_test_suite](#rust_test_suite)
3031
* [rust_toolchain](#rust_toolchain)
@@ -893,6 +894,25 @@ When building the whole binary in Bazel, use `rust_library` instead.
893894
| <a id="rust_static_library-version"></a>version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" |
894895

895896

897+
<a id="#rust_stdlib_filegroup"></a>
898+
899+
## rust_stdlib_filegroup
900+
901+
<pre>
902+
rust_stdlib_filegroup(<a href="#rust_stdlib_filegroup-name">name</a>, <a href="#rust_stdlib_filegroup-srcs">srcs</a>)
903+
</pre>
904+
905+
A dedicated filegroup-like rule for Rust stdlib artifacts.
906+
907+
**ATTRIBUTES**
908+
909+
910+
| Name | Description | Type | Mandatory | Default |
911+
| :------------- | :------------- | :------------- | :------------- | :------------- |
912+
| <a id="rust_stdlib_filegroup-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
913+
| <a id="rust_stdlib_filegroup-srcs"></a>srcs | The list of targets/files that are components of the rust-stdlib file group | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | required | |
914+
915+
896916
<a id="#rust_test"></a>
897917

898918
## rust_test

docs/rust_repositories.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@
66
* [rust_toolchain](#rust_toolchain)
77
* [rust_toolchain_repository](#rust_toolchain_repository)
88
* [rust_toolchain_repository_proxy](#rust_toolchain_repository_proxy)
9+
* [rust_stdlib_filegroup](#rust_stdlib_filegroup)
10+
11+
<a id="#rust_stdlib_filegroup"></a>
12+
13+
## rust_stdlib_filegroup
14+
15+
<pre>
16+
rust_stdlib_filegroup(<a href="#rust_stdlib_filegroup-name">name</a>, <a href="#rust_stdlib_filegroup-srcs">srcs</a>)
17+
</pre>
18+
19+
A dedicated filegroup-like rule for Rust stdlib artifacts.
20+
21+
**ATTRIBUTES**
22+
23+
24+
| Name | Description | Type | Mandatory | Default |
25+
| :------------- | :------------- | :------------- | :------------- | :------------- |
26+
| <a id="rust_stdlib_filegroup-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
27+
| <a id="rust_stdlib_filegroup-srcs"></a>srcs | The list of targets/files that are components of the rust-stdlib file group | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | required | |
28+
929

1030
<a id="#rust_toolchain"></a>
1131

docs/symbols.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ load(
6262
)
6363
load(
6464
"@rules_rust//rust:toolchain.bzl",
65+
_rust_stdlib_filegroup = "rust_stdlib_filegroup",
6566
_rust_toolchain = "rust_toolchain",
6667
)
6768
load(
@@ -96,6 +97,7 @@ rust_bindgen_repositories = _rust_bindgen_repositories
9697
rust_toolchain = _rust_toolchain
9798
rust_proto_toolchain = _rust_proto_toolchain
9899
rust_proto_repositories = _rust_proto_repositories
100+
rust_stdlib_filegroup = _rust_stdlib_filegroup
99101

100102
cargo_build_script = _cargo_build_script
101103

rust/defs.bzl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
"""Public entry point to all Rust rules and supported APIs."""
1616

17+
load(
18+
"//rust:toolchain.bzl",
19+
_rust_stdlib_filegroup = "rust_stdlib_filegroup",
20+
)
1721
load(
1822
"//rust/private:clippy.bzl",
1923
_rust_clippy = "rust_clippy",
@@ -111,3 +115,6 @@ rustfmt_aspect = _rustfmt_aspect
111115

112116
rustfmt_test = _rustfmt_test
113117
# See @rules_rust//rust/private:rustfmt.bzl for a complete description.
118+
119+
rust_stdlib_filegroup = _rust_stdlib_filegroup
120+
# See @rules_rust//rust:toolchain.bzl for a complete description.

rust/private/common.bzl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ which exports the `rust_common` struct.
2323
In the Bazel lingo, `rust_common` gives the access to the Rust Sandwich API.
2424
"""
2525

26-
load(":providers.bzl", "CrateInfo", "DepInfo")
26+
load(":providers.bzl", "CrateInfo", "DepInfo", "StdLibInfo")
2727

2828
def _create_crate_info(**kwargs):
2929
"""A constructor for a `CrateInfo` provider
@@ -43,4 +43,5 @@ rust_common = struct(
4343
create_crate_info = _create_crate_info,
4444
crate_info = CrateInfo,
4545
dep_info = DepInfo,
46+
stdlib_info = StdLibInfo,
4647
)

rust/private/providers.bzl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,20 @@ DepInfo = provider(
4242
"transitive_noncrates": "depset[LinkerInput]: All transitive dependencies that aren't crates.",
4343
},
4444
)
45+
46+
StdLibInfo = provider(
47+
doc = (
48+
"A collection of files either found within the `rust-stdlib` artifact or " +
49+
"generated based on existing files."
50+
),
51+
fields = {
52+
"alloc_files": "List[File]: `.a` files related to the `alloc` module.",
53+
"between_alloc_and_core_files": "List[File]: `.a` files related to the `compiler_builtins` module.",
54+
"between_core_and_std_files": "List[File]: `.a` files related to all modules except `adler`, `alloc`, `compiler_builtins`, `core`, and `std`.",
55+
"core_files": "List[File]: `.a` files related to the `core` and `adler` modules",
56+
"dot_a_files": "Depset[File]: Generated `.a` files",
57+
"srcs": "List[Target]: The original `src` attribute.",
58+
"std_files": "Depset[File]: `.a` files associated with the `std` module.",
59+
"std_rlibs": "List[File]: All `.rlib` files",
60+
},
61+
)

rust/private/repository_utils.bzl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ def BUILD_for_clippy(target_triple):
138138
return _build_file_for_clippy_template.format(binary_ext = system_to_binary_ext(system))
139139

140140
_build_file_for_stdlib_template = """\
141-
filegroup(
141+
load("@rules_rust//rust:toolchain.bzl", "rust_stdlib_filegroup")
142+
143+
rust_stdlib_filegroup(
142144
name = "rust_lib-{target_triple}",
143145
srcs = glob(
144146
[

rust/toolchain.bzl

Lines changed: 82 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,32 @@
11
"""The rust_toolchain rule definition and implementation."""
22

3-
load(
4-
"//rust/private:utils.bzl",
5-
"find_cc_toolchain",
6-
)
3+
load("//rust/private:common.bzl", "rust_common")
4+
load("//rust/private:utils.bzl", "dedent", "find_cc_toolchain")
75

8-
def _make_dota(ctx, f):
6+
def _make_dota(ctx, file):
97
"""Add a symlink for a file that ends in .a, so it can be used as a staticlib.
108
119
Args:
1210
ctx (ctx): The rule's context object.
13-
f (File): The file to symlink.
11+
file (File): The file to symlink.
1412
1513
Returns:
1614
The symlink's File.
1715
"""
18-
dot_a = ctx.actions.declare_file(f.basename + ".a", sibling = f)
19-
ctx.actions.symlink(output = dot_a, target_file = f)
16+
dot_a = ctx.actions.declare_file(file.basename + ".a", sibling = file)
17+
ctx.actions.symlink(output = dot_a, target_file = file)
2018
return dot_a
2119

22-
def _ltl(library, ctx, cc_toolchain, feature_configuration):
23-
return cc_common.create_library_to_link(
24-
actions = ctx.actions,
25-
feature_configuration = feature_configuration,
26-
cc_toolchain = cc_toolchain,
27-
static_library = library,
28-
pic_static_library = library,
29-
)
30-
31-
def _make_libstd_and_allocator_ccinfo(ctx, rust_lib, allocator_library):
32-
"""Make the CcInfo (if possible) for libstd and allocator libraries.
20+
def _rust_stdlib_filegroup_impl(ctx):
21+
rust_lib = ctx.files.srcs
22+
dot_a_files = []
23+
between_alloc_and_core_files = []
24+
core_files = []
25+
between_core_and_std_files = []
26+
std_files = []
27+
alloc_files = []
3328

34-
Args:
35-
ctx (ctx): The rule's context object.
36-
rust_lib: The rust standard library.
37-
allocator_library: The target to use for providing allocator functions.
38-
39-
40-
Returns:
41-
A CcInfo object for the required libraries, or None if no such libraries are available.
42-
"""
43-
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
44-
link_inputs = []
45-
std_rlibs = [f for f in rust_lib.files.to_list() if f.basename.endswith(".rlib")]
29+
std_rlibs = [f for f in rust_lib if f.basename.endswith(".rlib")]
4630
if std_rlibs:
4731
# std depends on everything
4832
#
@@ -71,26 +55,88 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_lib, allocator_library):
7155
print("File partitioned: {}".format(f.basename))
7256
fail("rust_toolchain couldn't properly partition rlibs in rust_lib. Partitioned {} out of {} files. This is probably a bug in the rule implementation.".format(partitioned_files_len, len(dot_a_files)))
7357

58+
return [
59+
DefaultInfo(
60+
files = depset(ctx.files.srcs),
61+
),
62+
rust_common.stdlib_info(
63+
std_rlibs = std_rlibs,
64+
dot_a_files = dot_a_files,
65+
between_alloc_and_core_files = between_alloc_and_core_files,
66+
core_files = core_files,
67+
between_core_and_std_files = between_core_and_std_files,
68+
std_files = std_files,
69+
alloc_files = alloc_files,
70+
),
71+
]
72+
73+
rust_stdlib_filegroup = rule(
74+
doc = "A dedicated filegroup-like rule for Rust stdlib artifacts.",
75+
implementation = _rust_stdlib_filegroup_impl,
76+
attrs = {
77+
"srcs": attr.label_list(
78+
allow_files = True,
79+
doc = "The list of targets/files that are components of the rust-stdlib file group",
80+
mandatory = True,
81+
),
82+
},
83+
)
84+
85+
def _ltl(library, ctx, cc_toolchain, feature_configuration):
86+
return cc_common.create_library_to_link(
87+
actions = ctx.actions,
88+
feature_configuration = feature_configuration,
89+
cc_toolchain = cc_toolchain,
90+
static_library = library,
91+
pic_static_library = library,
92+
)
93+
94+
def _make_libstd_and_allocator_ccinfo(ctx, rust_lib, allocator_library):
95+
"""Make the CcInfo (if possible) for libstd and allocator libraries.
96+
97+
Args:
98+
ctx (ctx): The rule's context object.
99+
rust_lib: The rust standard library.
100+
allocator_library: The target to use for providing allocator functions.
101+
102+
103+
Returns:
104+
A CcInfo object for the required libraries, or None if no such libraries are available.
105+
"""
106+
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
107+
link_inputs = []
108+
109+
if not rust_common.stdlib_info in ctx.attr.rust_lib:
110+
fail(dedent("""\
111+
{} --
112+
The `rust_lib` must be a target providing `rust_common.stdlib_info`
113+
(typically `rust_stdlib_filegroup` rule from @rules_rust//rust:defs.bzl).
114+
See https://github.com/bazelbuild/rules_rust/pull/802 for more information.
115+
116+
""").format(ctx.label))
117+
rust_stdlib_info = ctx.attr.rust_lib[rust_common.stdlib_info]
118+
119+
if rust_stdlib_info.std_rlibs:
74120
alloc_inputs = depset(
75-
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in alloc_files],
121+
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.alloc_files],
76122
)
77123
between_alloc_and_core_inputs = depset(
78-
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in between_alloc_and_core_files],
124+
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.between_alloc_and_core_files],
79125
transitive = [alloc_inputs],
80126
order = "topological",
81127
)
82128
core_inputs = depset(
83-
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in core_files],
129+
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.core_files],
84130
transitive = [between_alloc_and_core_inputs],
85131
order = "topological",
86132
)
87133
between_core_and_std_inputs = depset(
88-
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in between_core_and_std_files],
134+
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.between_core_and_std_files],
89135
transitive = [core_inputs],
90136
order = "topological",
91137
)
92138
std_inputs = depset(
93-
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in std_files],
139+
[_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.std_files],
94140
transitive = [between_core_and_std_inputs],
95141
order = "topological",
96142
)

0 commit comments

Comments
 (0)