Skip to content

Commit af049fc

Browse files
authored
Add rust-analyzer toolchains (#60)
1 parent 80e1702 commit af049fc

23 files changed

Lines changed: 885 additions & 18 deletions

.bazelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ common --repo_env=BAZEL_NO_APPLE_CPP_TOOLCHAIN=1
99
common --repo_contents_cache=~/bazel_repo_contents_cache
1010
common --disk_cache=~/bazel_cache
1111

12+
common --@llvm//config:experimental_stub_libgcc_s
13+
common --enable_platform_specific_config
14+
common:linux --host_platform=//:local_gnu_platform
15+
1216
common:remote --jobs=800

BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ license(
1717
kind = "@package_metadata//licenses/spdx:Apache-2.0",
1818
text = "LICENSE",
1919
)
20+
21+
platform(
22+
name = "local_gnu_platform",
23+
parents = ["@platforms//host"],
24+
constraint_values = [
25+
"@llvm//constraints/libc:gnu.2.28",
26+
],
27+
)

MODULE.bazel

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use_repo(
4949
bazel_dep(name = "bazel_lib", version = "3.0.0")
5050
bazel_dep(name = "bazel_features", version = "1.32.0")
5151
bazel_dep(name = "bazel_skylib", version = "1.4.1")
52-
bazel_dep(name = "package_metadata", version = "0.0.5")
52+
bazel_dep(name = "package_metadata", version = "0.0.7")
5353
bazel_dep(name = "platforms", version = "0.0.5")
5454
bazel_dep(name = "protobuf", version = "34.0.bcr.1", repo_name = "com_google_protobuf")
5555
bazel_dep(name = "rules_cc", version = "0.2.8")
@@ -61,6 +61,20 @@ tel = use_extension("@aspect_tools_telemetry//:extension.bzl", "telemetry")
6161
use_repo(tel, "aspect_tools_telemetry_report")
6262

6363
crate = use_extension("//rs:extensions.bzl", "crate")
64+
crate.from_cargo(
65+
name = "rrra",
66+
cargo_lock = "//tools/rust_analyzer:Cargo.lock",
67+
cargo_toml = "//tools/rust_analyzer:Cargo.toml",
68+
platform_triples = [
69+
"aarch64-apple-darwin",
70+
"aarch64-pc-windows-msvc",
71+
"aarch64-unknown-linux-gnu",
72+
"x86_64-apple-darwin",
73+
"x86_64-pc-windows-msvc",
74+
"x86_64-unknown-linux-gnu",
75+
],
76+
use_experimental_platforms = True,
77+
)
6478
crate.from_cargo(
6579
name = "rrprd",
6680
cargo_lock = "//rs/private/prost:Cargo.lock",
@@ -85,6 +99,7 @@ crate.annotation(
8599
crate = "protoc-gen-tonic",
86100
gen_binaries = ["protoc-gen-tonic"],
87101
)
102+
use_repo(crate, "rrra")
88103
use_repo(crate, "rrprd")
89104

90105
rules_rust_prost = use_extension("//rs/experimental:rules_rust_prost.bzl", "rules_rust_prost")
@@ -94,3 +109,13 @@ bazel_dep(name = "rules_go", version = "0.59.0", dev_dependency = True)
94109
bazel_dep(name = "gazelle", version = "0.47.0", dev_dependency = True)
95110
bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.8.2", dev_dependency = True)
96111
bazel_dep(name = "buildifier_prebuilt", version = "6.1.2", dev_dependency = True)
112+
113+
register_toolchains(
114+
"@default_rust_toolchains//:all",
115+
dev_dependency = True,
116+
)
117+
118+
register_toolchains(
119+
"@llvm//toolchain:all",
120+
dev_dependency = True,
121+
)

MODULE.bazel.lock

Lines changed: 32 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ register_toolchains("@rust_toolchains//:all")
9393

9494
In this mode, keep `use_experimental_platforms = False` (the default) in `crate.from_cargo(...)`.
9595

96+
## rust-analyzer Integration
97+
98+
`rust-analyzer` targets are accessible via either the legacy `@rules_rust` paths or `@rules_rs` paths.
99+
100+
Example usage:
101+
102+
```bzl
103+
bazel run @rules_rs//tools/rust_analyzer:gen_rust_project -- --help
104+
```
105+
106+
See https://bazelbuild.github.io/rules_rust/rust_analyzer.html#vscode and the sections below that for more setup instructions.
107+
96108
## Dependency Resolution
97109

98110
`rules_rs` uses its own `crate_universe` implementation through `crate.from_cargo`:
@@ -225,6 +237,7 @@ At minimum, set an explicit `--host_platform` that adds your ABI constraint on t
225237
`.bazelrc`:
226238

227239
```bazelrc
240+
common --enable_platform_specific_config
228241
common:linux --host_platform=//platforms:local_gnu
229242
common:windows --host_platform=//platforms:local_windows_msvc
230243
```

rs/experimental/rules_rust.bzl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ def _rules_rust_impl(mctx):
3131

3232
http_archive(
3333
name = "rules_rust",
34-
integrity = "sha256-xT7zyL35CDK5b7iKdKL+WchslRZsnXDXuBMHiqVD0ps=",
35-
strip_prefix = "rules_rust-7ed8a24a37be47378b8a266ae3016148b9cb5c49",
36-
url = "https://github.com/hermeticbuild/rules_rust/archive/7ed8a24a37be47378b8a266ae3016148b9cb5c49.tar.gz",
34+
integrity = "sha256-vZfWz/bMaLs3Q/xRtj0qEVqQa47Xwd2iK6GgYJZqgUU=",
35+
strip_prefix = "rules_rust-e1ed0e436cb319700887823c7df421c5684bc6da",
36+
url = "https://github.com/hermeticbuild/rules_rust/archive/e1ed0e436cb319700887823c7df421c5684bc6da.tar.gz",
3737
patches = patches,
3838
patch_strip = strip,
3939
)

rs/experimental/toolchains/BUILD.bazel

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ bzl_library(
1313
],
1414
)
1515

16+
bzl_library(
17+
name = "declare_rust_analyzer_toolchains",
18+
srcs = ["declare_rust_analyzer_toolchains.bzl"],
19+
deps = [
20+
":toolchain_utils",
21+
"//rs/experimental/platforms:triples",
22+
"@rules_rust//rust:bzl_lib",
23+
"@rules_rust//rust/platform:bzl_lib",
24+
"@rules_rust//rust/private:bzl_lib",
25+
],
26+
)
27+
1628
bzl_library(
1729
name = "declare_rustfmt_toolchains",
1830
srcs = ["declare_rustfmt_toolchains.bzl"],
@@ -33,7 +45,9 @@ bzl_library(
3345
"//rs/private:cargo_repository",
3446
"//rs/private:clippy_repository",
3547
"//rs/private:host_tools_repository",
48+
"//rs/private:rust_analyzer_repository",
3649
"//rs/private:rust_repository_utils",
50+
"//rs/private:rust_src_repository",
3751
"//rs/private:rustc_repository",
3852
"//rs/private:rustfmt_repository",
3953
"//rs/private:stdlib_repository",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
load("@rules_rust//rust:toolchain.bzl", "rust_analyzer_toolchain")
2+
load("@rules_rust//rust/platform:triple.bzl", _parse_triple = "triple")
3+
load(
4+
"@rules_rust//rust/private:repository_utils.bzl",
5+
"includes_rust_analyzer_proc_macro_srv",
6+
)
7+
load("//rs/experimental/platforms:triples.bzl", "SUPPORTED_EXEC_TRIPLES")
8+
load("//rs/experimental/toolchains:toolchain_utils.bzl", "sanitize_version")
9+
10+
def _channel(version):
11+
if version.startswith("nightly"):
12+
return "nightly"
13+
if version.startswith("beta"):
14+
return "beta"
15+
return "stable"
16+
17+
def _parse_version(version):
18+
if "/" in version:
19+
return version.split("/", 1)
20+
return version, None
21+
22+
def declare_rust_analyzer_toolchains(
23+
*,
24+
version,
25+
rust_analyzer_version,
26+
execs = SUPPORTED_EXEC_TRIPLES):
27+
version_key = sanitize_version(version)
28+
rust_analyzer_version_key = sanitize_version(rust_analyzer_version)
29+
channel = _channel(version)
30+
rust_analyzer_base_version, rust_analyzer_iso_date = _parse_version(rust_analyzer_version)
31+
32+
for triple in execs:
33+
exec_triple = _parse_triple(triple)
34+
triple_suffix = exec_triple.system + "_" + exec_triple.arch
35+
36+
rustc_repo_label = "@rustc_{}_{}//:".format(triple_suffix, rust_analyzer_version_key)
37+
rust_analyzer_repo_label = "@rust_analyzer_{}_{}//:".format(triple_suffix, rust_analyzer_version_key)
38+
rust_src_repo_label = "@rust_src_{}//lib/rustlib/src:rustc_srcs".format(rust_analyzer_version_key)
39+
40+
rust_analyzer_toolchain_name = "{}_{}_{}_rust_analyzer_toolchain".format(
41+
exec_triple.system,
42+
exec_triple.arch,
43+
version_key,
44+
)
45+
46+
rust_analyzer_toolchain_kwargs = dict(
47+
name = rust_analyzer_toolchain_name,
48+
rust_analyzer = "{}rust_analyzer".format(rust_analyzer_repo_label),
49+
rustc = "{}rustc".format(rustc_repo_label),
50+
rustc_srcs = rust_src_repo_label,
51+
visibility = ["//visibility:public"],
52+
)
53+
54+
if includes_rust_analyzer_proc_macro_srv(rust_analyzer_base_version, rust_analyzer_iso_date):
55+
rust_analyzer_toolchain_kwargs["proc_macro_srv"] = "{}rust_analyzer_proc_macro_srv".format(rustc_repo_label)
56+
57+
rust_analyzer_toolchain(**rust_analyzer_toolchain_kwargs)
58+
59+
native.toolchain(
60+
name = "{}_{}_rust_analyzer_{}".format(exec_triple.system, exec_triple.arch, version_key),
61+
exec_compatible_with = [
62+
"@platforms//os:" + exec_triple.system,
63+
"@platforms//cpu:" + exec_triple.arch,
64+
],
65+
target_compatible_with = [],
66+
target_settings = [
67+
"@rules_rust//rust/toolchain/channel:" + channel,
68+
],
69+
toolchain = rust_analyzer_toolchain_name,
70+
toolchain_type = "@rules_rust//rust/rust_analyzer:toolchain_type",
71+
visibility = ["//visibility:public"],
72+
)

rs/experimental/toolchains/module_extension.bzl

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ load("//rs/experimental/toolchains:toolchain_utils.bzl", "sanitize_triple", "san
1212
load("//rs/private:cargo_repository.bzl", "cargo_repository")
1313
load("//rs/private:clippy_repository.bzl", "clippy_repository")
1414
load("//rs/private:host_tools_repository.bzl", "host_tools_repository")
15+
load("//rs/private:rust_analyzer_repository.bzl", "rust_analyzer_repository")
16+
load("//rs/private:rust_src_repository.bzl", "rust_src_repository")
1517
load("//rs/private:rustc_repository.bzl", "rustc_repository")
1618
load("//rs/private:rustfmt_repository.bzl", "rustfmt_repository")
1719
load("//rs/private:stdlib_repository.bzl", "stdlib_repository")
@@ -65,6 +67,10 @@ _TOOLCHAIN_TAG = tag_class(
6567
doc = "Rustfmt version (e.g. 1.86.0 or nightly/2025-04-03)",
6668
default = "",
6769
),
70+
"rust_analyzer_version": attr.string(
71+
doc = "Rust-analyzer version (e.g. 1.86.0 or nightly/2025-04-03)",
72+
default = "",
73+
),
6874
"edition": attr.string(
6975
doc = "Default edition to apply to toolchains.",
7076
default = _DEFAULT_EDITION,
@@ -106,17 +112,20 @@ def _toolchains_impl(mctx):
106112
name = _DEFAULT_TOOLCHAIN_REPO_NAME,
107113
version = _DEFAULT_RUSTC_VERSION,
108114
rustfmt_version = "",
115+
rust_analyzer_version = "",
109116
edition = _DEFAULT_EDITION,
110117
extra_rustc_flags = {},
111118
extra_exec_rustc_flags = {},
112119
))
113120

114121
versions = set([])
115122
rustfmt_versions = set([])
123+
rust_analyzer_versions = set([])
116124

117125
for tag in version_tags:
118126
versions.add(tag.version)
119127
rustfmt_versions.add(tag.rustfmt_version or tag.version)
128+
rust_analyzer_versions.add(tag.rust_analyzer_version or tag.version)
120129

121130
existing_facts = getattr(mctx, "facts", {}) or {}
122131
pending_downloads = {}
@@ -165,6 +174,17 @@ def _toolchains_impl(mctx):
165174
for tool_name in ["rustc", "rustfmt"]:
166175
_request_sha(tool_name, base_version, iso_date, exec_triple)
167176

177+
for version in rust_analyzer_versions:
178+
base_version, iso_date = _parse_version(version)
179+
180+
_request_sha("rust-src", base_version, iso_date, None)
181+
182+
for triple in SUPPORTED_EXEC_TRIPLES:
183+
exec_triple = _parse_triple(triple)
184+
185+
for tool_name in ["rustc", "rust-analyzer"]:
186+
_request_sha(tool_name, base_version, iso_date, exec_triple)
187+
168188
# Finish downloads and record facts.
169189
for archive_path, req in pending_downloads.items():
170190
req.token.wait()
@@ -182,7 +202,7 @@ def _toolchains_impl(mctx):
182202
host_arch = _normalize_arch_name(mctx.os.arch)
183203
host_cargo_repo = None
184204

185-
for version in versions | rustfmt_versions:
205+
for version in versions | rustfmt_versions | rust_analyzer_versions:
186206
version_key = sanitize_version(version)
187207
base_version, iso_date = _parse_version(version)
188208

@@ -249,6 +269,29 @@ def _toolchains_impl(mctx):
249269
rustc_repo_build_file = "@rustc_{}_{}//:BUILD.bazel".format(triple_suffix, version_key),
250270
)
251271

272+
for version in rust_analyzer_versions:
273+
version_key = sanitize_version(version)
274+
base_version, iso_date = _parse_version(version)
275+
276+
rust_src_repository(
277+
name = "rust_src_{}".format(version_key),
278+
version = base_version,
279+
iso_date = iso_date,
280+
sha256 = _sha_for("rust-src", base_version, iso_date, None),
281+
)
282+
283+
for triple in SUPPORTED_EXEC_TRIPLES:
284+
exec_triple = _parse_triple(triple)
285+
triple_suffix = exec_triple.system + "_" + exec_triple.arch
286+
287+
rust_analyzer_repository(
288+
name = "rust_analyzer_{}_{}".format(triple_suffix, version_key),
289+
triple = triple,
290+
version = base_version,
291+
iso_date = iso_date,
292+
sha256 = _sha_for("rust-analyzer", base_version, iso_date, exec_triple),
293+
)
294+
252295
host_tools_repository(
253296
name = "rs_rust_host_tools",
254297
host_cargo_repo = host_cargo_repo,
@@ -264,10 +307,12 @@ def _toolchains_impl(mctx):
264307
for tag in version_tags:
265308
repo_name = tag.name
266309
rustfmt_version = tag.rustfmt_version or tag.version
310+
rust_analyzer_version = tag.rust_analyzer_version or tag.version
267311
existing = repo_configs.get(repo_name)
268312
if existing and (
269313
existing.version != tag.version or
270314
(existing.rustfmt_version or existing.version) != rustfmt_version or
315+
(existing.rust_analyzer_version or existing.version) != rust_analyzer_version or
271316
existing.edition != tag.edition or
272317
existing.extra_rustc_flags != tag.extra_rustc_flags or
273318
existing.extra_exec_rustc_flags != tag.extra_exec_rustc_flags
@@ -280,6 +325,7 @@ def _toolchains_impl(mctx):
280325
name = repo_name,
281326
version = tag.version,
282327
rustfmt_version = rustfmt_version,
328+
rust_analyzer_version = rust_analyzer_version,
283329
edition = tag.edition,
284330
extra_rustc_flags = tag.extra_rustc_flags,
285331
extra_exec_rustc_flags = tag.extra_exec_rustc_flags,

rs/private/BUILD.bazel

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,27 @@ bzl_library(
121121
],
122122
)
123123

124+
bzl_library(
125+
name = "rust_analyzer_repository",
126+
srcs = ["rust_analyzer_repository.bzl"],
127+
visibility = ["//rs:__subpackages__"],
128+
deps = [
129+
"//rs/private:rust_repository_utils",
130+
"@rules_rust//rust/platform:bzl_lib",
131+
"@rules_rust//rust/private:bzl_lib",
132+
],
133+
)
134+
135+
bzl_library(
136+
name = "rust_src_repository",
137+
srcs = ["rust_src_repository.bzl"],
138+
visibility = ["//rs:__subpackages__"],
139+
deps = [
140+
"@bazel_tools//tools/build_defs/repo:utils.bzl",
141+
"@rules_rust//rust/private:bzl_lib",
142+
],
143+
)
144+
124145
bzl_library(
125146
name = "rustc_repository",
126147
srcs = ["rustc_repository.bzl"],
@@ -148,6 +169,7 @@ bzl_library(
148169
srcs = ["toolchains_repository.bzl"],
149170
visibility = ["//rs:__subpackages__"],
150171
deps = [
172+
"//rs/experimental/toolchains:declare_rust_analyzer_toolchains",
151173
"//rs/experimental/toolchains:declare_rustc_toolchains",
152174
"//rs/experimental/toolchains:declare_rustfmt_toolchains",
153175
],

0 commit comments

Comments
 (0)