Skip to content

Commit 76c97eb

Browse files
committed
Add opt-in nightly rustc-dev toolchains
1 parent b332517 commit 76c97eb

14 files changed

Lines changed: 517 additions & 10 deletions

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,36 @@ https://bazelbuild.github.io/rules_rust/rust_analyzer.html#vscode
132132

133133
## Advanced Options
134134

135+
<details>
136+
<summary>Enable nightly rustc-dev components</summary>
137+
138+
Nightly crates that depend on `rustc_private` need the `rustc-dev` component in the
139+
compiler sysroot. Opt into that only for the nightly toolchain that needs it:
140+
141+
```bzl
142+
toolchains.toolchain(
143+
name = "nightly_rust_toolchains",
144+
edition = "2024",
145+
include_rustc_dev = True,
146+
version = "nightly/2026-03-05",
147+
)
148+
use_repo(toolchains, "nightly_rust_toolchains")
149+
register_toolchains("@nightly_rust_toolchains//:all")
150+
```
151+
152+
`include_rustc_dev` is accepted only for nightly Rust versions. It keeps the default
153+
toolchain path unchanged and exposes separate `*_with_dev` toolchains when a build sets
154+
both:
155+
156+
```bash
157+
bazel build \
158+
--@rules_rust//rust/toolchain/channel=nightly \
159+
--@rules_rs//rs/toolchains/rustc_dev:enabled \
160+
//...
161+
```
162+
163+
</details>
164+
135165
<details>
136166
<summary>Use legacy rules_rust toolchains or platforms</summary>
137167

rs/private/BUILD.bazel

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,27 @@ bzl_library(
184184
],
185185
)
186186

187+
bzl_library(
188+
name = "rustc_dev_repository",
189+
srcs = ["rustc_dev_repository.bzl"],
190+
visibility = ["//rs:__subpackages__"],
191+
deps = [
192+
"//rs/private:rust_repository_utils",
193+
"@rules_rust//rust/platform:bzl_lib",
194+
],
195+
)
196+
197+
bzl_library(
198+
name = "rustc_with_dev_repository",
199+
srcs = ["rustc_with_dev_repository.bzl"],
200+
visibility = ["//rs:__subpackages__"],
201+
deps = [
202+
"@bazel_features//:features",
203+
"@rules_rust//rust/platform:bzl_lib",
204+
"@rules_rust//rust/private:bzl_lib",
205+
],
206+
)
207+
187208
bzl_library(
188209
name = "stdlib_repository",
189210
srcs = ["stdlib_repository.bzl"],
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
load("@rules_rust//rust/platform:triple.bzl", "triple")
2+
load(":rust_repository_utils.bzl", "RUST_REPOSITORY_COMMON_ATTR", "download_and_extract")
3+
4+
def _rustc_dev_repository_impl(rctx):
5+
exec_triple = triple(rctx.attr.triple)
6+
download_and_extract(rctx, "rustc-dev", "rustc-dev", exec_triple)
7+
8+
rctx.file(
9+
"BUILD.bazel",
10+
"""\
11+
filegroup(
12+
name = "rustc_dev_libs",
13+
srcs = glob(
14+
["lib/rustlib/{triple}/lib/*.rlib"],
15+
allow_empty = True,
16+
),
17+
visibility = ["//visibility:public"],
18+
)
19+
""".format(triple = exec_triple.str),
20+
)
21+
22+
return rctx.repo_metadata(reproducible = True)
23+
24+
rustc_dev_repository = repository_rule(
25+
implementation = _rustc_dev_repository_impl,
26+
attrs = RUST_REPOSITORY_COMMON_ATTR,
27+
)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
load("@bazel_features//:features.bzl", "bazel_features")
2+
load("@rules_rust//rust/platform:triple.bzl", "triple")
3+
load(
4+
"@rules_rust//rust/private:repository_utils.bzl",
5+
"BUILD_for_compiler",
6+
)
7+
8+
def _symlink_children(rctx, source_dir, destination_dir):
9+
if not source_dir.exists or not source_dir.is_dir:
10+
return
11+
12+
rctx.file("{}/.generated".format(destination_dir), "")
13+
for entry in source_dir.readdir():
14+
if entry.is_dir or entry.basename.startswith("."):
15+
continue
16+
17+
destination = "{}/{}".format(destination_dir, entry.basename)
18+
if not rctx.path(destination).exists:
19+
rctx.symlink(entry, destination)
20+
21+
def _rustc_with_dev_repository_impl(rctx):
22+
exec_triple = triple(rctx.attr.triple)
23+
rustc_repo_root = rctx.path(rctx.attr.rustc_repo_build_file).dirname
24+
rustc_dev_repo_root = rctx.path(rctx.attr.rustc_dev_repo_build_file).dirname
25+
26+
# Keep the ordinary rustc repository lean. This merged sysroot is materialized
27+
# only when a dev-enabled toolchain is actually selected.
28+
rctx.symlink(rustc_repo_root.get_child("bin"), "bin")
29+
30+
rustc_lib_root = rustc_repo_root.get_child("lib")
31+
rustc_rustlib_root = rustc_lib_root.get_child("rustlib").get_child(exec_triple.str)
32+
rustc_dev_lib_root = rustc_dev_repo_root.get_child("lib").get_child("rustlib").get_child(exec_triple.str)
33+
34+
_symlink_children(rctx, rustc_lib_root, "lib")
35+
rctx.symlink(
36+
rustc_rustlib_root.get_child("bin"),
37+
"lib/rustlib/{}/bin".format(exec_triple.str),
38+
)
39+
_symlink_children(
40+
rctx,
41+
rustc_rustlib_root.get_child("codegen-backends"),
42+
"lib/rustlib/{}/codegen-backends".format(exec_triple.str),
43+
)
44+
_symlink_children(
45+
rctx,
46+
rustc_rustlib_root.get_child("lib"),
47+
"lib/rustlib/{}/lib".format(exec_triple.str),
48+
)
49+
_symlink_children(
50+
rctx,
51+
rustc_dev_lib_root.get_child("lib"),
52+
"lib/rustlib/{}/lib".format(exec_triple.str),
53+
)
54+
55+
# `rustc_private` crates link against compiler `.rlib`s from rustc-dev.
56+
# The upstream compiler BUILD omits `.rlib`s because ordinary toolchains do
57+
# not need them, so extend the merged sysroot manifest only for this variant.
58+
build_file = BUILD_for_compiler(exec_triple, include_objcopy = True)
59+
build_file = build_file.replace(
60+
'"lib/rustlib/{}/lib/*.rmeta",'.format(exec_triple.str),
61+
'\n'.join([
62+
'"lib/rustlib/{}/lib/*.rmeta",'.format(exec_triple.str),
63+
' "lib/rustlib/{}/lib/*.rlib",'.format(exec_triple.str),
64+
]),
65+
)
66+
rctx.file("BUILD.bazel", build_file)
67+
68+
return rctx.repo_metadata(
69+
reproducible = bazel_features.external_deps.repo_rules_relativize_symlinks,
70+
)
71+
72+
rustc_with_dev_repository = repository_rule(
73+
implementation = _rustc_with_dev_repository_impl,
74+
attrs = {
75+
"rustc_repo_build_file": attr.label(allow_single_file = True, mandatory = True),
76+
"rustc_dev_repo_build_file": attr.label(allow_single_file = True, mandatory = True),
77+
"triple": attr.string(mandatory = True),
78+
},
79+
)

rs/private/toolchains_repository.bzl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ load("@rules_rs//rs/toolchains:declare_rustfmt_toolchains.bzl", "declare_rustfmt
99
declare_rustc_toolchains(
1010
version = {version},
1111
edition = {edition},
12+
include_rustc_dev = {include_rustc_dev},
1213
extra_rustc_flags = {extra_rustc_flags},
1314
extra_exec_rustc_flags = {extra_exec_rustc_flags},
1415
)
@@ -28,6 +29,7 @@ declare_rust_analyzer_toolchains(
2829
rustfmt_version = repr(rctx.attr.rustfmt_version),
2930
rust_analyzer_version = repr(rctx.attr.rust_analyzer_version),
3031
edition = repr(rctx.attr.edition),
32+
include_rustc_dev = repr(rctx.attr.include_rustc_dev),
3133
extra_rustc_flags = repr(rctx.attr.extra_rustc_flags),
3234
extra_exec_rustc_flags = repr(rctx.attr.extra_exec_rustc_flags),
3335
),
@@ -42,6 +44,7 @@ toolchains_repository = repository_rule(
4244
"rustfmt_version": attr.string(mandatory = True),
4345
"rust_analyzer_version": attr.string(mandatory = True),
4446
"edition": attr.string(mandatory = True),
47+
"include_rustc_dev": attr.bool(),
4548
"extra_rustc_flags": attr.string_list_dict(),
4649
"extra_exec_rustc_flags": attr.string_list_dict(),
4750
},

rs/toolchains/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ bzl_library(
4848
"//rs/private:rust_analyzer_repository",
4949
"//rs/private:rust_repository_utils",
5050
"//rs/private:rust_src_repository",
51+
"//rs/private:rustc_dev_repository",
5152
"//rs/private:rustc_repository",
53+
"//rs/private:rustc_with_dev_repository",
5254
"//rs/private:rustfmt_repository",
5355
"//rs/private:stdlib_repository",
5456
"//rs/private:toolchains_repository",

rs/toolchains/declare_rustc_toolchains.bzl

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def declare_rustc_toolchains(
2020
*,
2121
version,
2222
edition,
23+
include_rustc_dev = False,
2324
extra_rustc_flags = {},
2425
extra_exec_rustc_flags = {},
2526
execs = SUPPORTED_EXEC_TRIPLES,
@@ -34,6 +35,7 @@ def declare_rustc_toolchains(
3435
triple_suffix = exec_triple.system + "_" + exec_triple.arch
3536

3637
rustc_repo_label = "@rustc_{}_{}//:".format(triple_suffix, version_key)
38+
rustc_with_dev_repo_label = "@rustc_with_dev_{}_{}//:".format(triple_suffix, version_key)
3739
cargo_repo_label = "@cargo_{}_{}//:".format(triple_suffix, version_key)
3840
clippy_repo_label = "@clippy_{}_{}//:".format(triple_suffix, version_key)
3941

@@ -42,6 +44,7 @@ def declare_rustc_toolchains(
4244
exec_triple.arch,
4345
version_key,
4446
)
47+
rust_toolchain_with_dev_name = rust_toolchain_name + "_with_dev"
4548

4649
rust_std_select = {}
4750
target_triple_select = {}
@@ -134,8 +137,44 @@ def declare_rustc_toolchains(
134137
**rust_toolchain_kwargs
135138
)
136139

140+
if include_rustc_dev:
141+
# Keep the ordinary toolchains registered for the default path, and
142+
# expose parallel dev-enabled variants only to configurations that
143+
# explicitly request the merged rustc-dev sysroot.
144+
rust_toolchain_with_dev_kwargs = dict(rust_toolchain_kwargs)
145+
rust_toolchain_with_dev_kwargs.update(
146+
rust_doc = "{}rustdoc".format(rustc_with_dev_repo_label),
147+
rustc = "{}rustc".format(rustc_with_dev_repo_label),
148+
rust_objcopy = "{}rust-objcopy".format(rustc_with_dev_repo_label),
149+
rustc_lib = "{}rustc_lib".format(rustc_with_dev_repo_label),
150+
)
151+
152+
rust_toolchain(
153+
name = rust_toolchain_with_dev_name,
154+
process_wrapper = "@rules_rust//util/process_wrapper",
155+
**rust_toolchain_with_dev_kwargs
156+
)
157+
158+
rust_toolchain(
159+
name = rust_toolchain_with_dev_name + "_bootstrap",
160+
bootstrapping = True,
161+
process_wrapper = "@rules_rust//util/process_wrapper:bootstrap_process_wrapper",
162+
**rust_toolchain_with_dev_kwargs
163+
)
164+
137165
for target_triple in targets:
138166
target_key = sanitize_triple(target_triple)
167+
bootstrapped_target_settings = [
168+
"@rules_rust//rust/private:bootstrapped",
169+
"@rules_rust//rust/toolchain/channel:" + channel,
170+
]
171+
bootstrapping_target_settings = [
172+
"@rules_rust//rust/private:bootstrapping",
173+
"@rules_rust//rust/toolchain/channel:" + channel,
174+
]
175+
if include_rustc_dev:
176+
bootstrapped_target_settings.append("@rules_rs//rs/toolchains/rustc_dev:disabled")
177+
bootstrapping_target_settings.append("@rules_rs//rs/toolchains/rustc_dev:disabled")
139178

140179
native.toolchain(
141180
name = "{}_{}_to_{}_{}".format(exec_triple.system, exec_triple.arch, target_key, version_key),
@@ -144,10 +183,7 @@ def declare_rustc_toolchains(
144183
"@platforms//cpu:" + exec_triple.arch,
145184
],
146185
target_compatible_with = triple_to_constraint_set(target_triple),
147-
target_settings = [
148-
"@rules_rust//rust/private:bootstrapped",
149-
"@rules_rust//rust/toolchain/channel:" + channel,
150-
],
186+
target_settings = bootstrapped_target_settings,
151187
toolchain = rust_toolchain_name,
152188
toolchain_type = "@rules_rust//rust:toolchain_type",
153189
visibility = ["//visibility:public"],
@@ -160,11 +196,43 @@ def declare_rustc_toolchains(
160196
"@platforms//cpu:" + exec_triple.arch,
161197
],
162198
target_compatible_with = triple_to_constraint_set(target_triple),
163-
target_settings = [
164-
"@rules_rust//rust/private:bootstrapping",
165-
"@rules_rust//rust/toolchain/channel:" + channel,
166-
],
199+
target_settings = bootstrapping_target_settings,
167200
toolchain = rust_toolchain_name + "_bootstrap",
168201
toolchain_type = "@rules_rust//rust:toolchain_type",
169202
visibility = ["//visibility:public"],
170203
)
204+
205+
if include_rustc_dev:
206+
native.toolchain(
207+
name = "{}_{}_to_{}_{}_with_dev".format(exec_triple.system, exec_triple.arch, target_key, version_key),
208+
exec_compatible_with = [
209+
"@platforms//os:" + exec_triple.system,
210+
"@platforms//cpu:" + exec_triple.arch,
211+
],
212+
target_compatible_with = triple_to_constraint_set(target_triple),
213+
target_settings = [
214+
"@rules_rust//rust/private:bootstrapped",
215+
"@rules_rust//rust/toolchain/channel:" + channel,
216+
"@rules_rs//rs/toolchains/rustc_dev:enabled_setting",
217+
],
218+
toolchain = rust_toolchain_with_dev_name,
219+
toolchain_type = "@rules_rust//rust:toolchain_type",
220+
visibility = ["//visibility:public"],
221+
)
222+
223+
native.toolchain(
224+
name = "{}_{}_to_{}_{}_bootstrap_with_dev".format(exec_triple.system, exec_triple.arch, target_key, version_key),
225+
exec_compatible_with = [
226+
"@platforms//os:" + exec_triple.system,
227+
"@platforms//cpu:" + exec_triple.arch,
228+
],
229+
target_compatible_with = triple_to_constraint_set(target_triple),
230+
target_settings = [
231+
"@rules_rust//rust/private:bootstrapping",
232+
"@rules_rust//rust/toolchain/channel:" + channel,
233+
"@rules_rs//rs/toolchains/rustc_dev:enabled_setting",
234+
],
235+
toolchain = rust_toolchain_with_dev_name + "_bootstrap",
236+
toolchain_type = "@rules_rust//rust:toolchain_type",
237+
visibility = ["//visibility:public"],
238+
)

0 commit comments

Comments
 (0)