Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ module(
bazel_dep(name = "bazel_features", version = "1.32.0")
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rust_toolchains", version = "0.68.1")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: there's an existing convention on BCR to prefix instead, so toolchains_rust ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a super strong opinion on this bikeshed, i just want it built. That said, if you take a look at https://registry.bazel.build/search?q=toolchains you'll see that:

  • 5 CC toolchains followed this convention (and toolchains_llvm_boostrapped only did because we were strongly urged, it will get renamed though)
  • 5 CC toolchains did xxx_toolchain instead
  • proto_toolchains also followed it, probably because you/Fabian picked the name :)
  • No other language did anything like this

So it doesn't feel like we necessarily need to draw a trend from a few isolated points, we should just pick whatever name is clearest IMO

bazel_dep(name = "rules_cc", version = "0.2.4")
bazel_dep(name = "rules_license", version = "1.0.0")
bazel_dep(name = "rules_shell", version = "0.6.1")
bazel_dep(name = "apple_support", version = "1.24.1", repo_name = "build_bazel_apple_support")

bazel_dep(name = "rust_toolchains", version = "0.0.1")
local_path_override(
module_name = "rust_toolchains",
path = "rust_toolchains",
)

internal_deps = use_extension("//rust/private:internal_extensions.bzl", "i")
use_repo(
internal_deps,
Expand Down Expand Up @@ -45,10 +52,10 @@ use_repo(

rust = use_extension("//rust:extensions.bzl", "rust")
rust.toolchain(edition = "2021")
use_repo(rust, "rust_toolchains")
use_repo(rust, rules_rust_toolchains = "rust_toolchains")

register_toolchains(
"@rust_toolchains//:all",
"@rules_rust_toolchains//:all",
)

rust_host_tools = use_extension("//rust:extensions.bzl", "rust_host_tools")
Expand Down
31 changes: 17 additions & 14 deletions cargo/private/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ load(
"deduplicate",
"expand_dict_value_locations",
"find_cc_toolchain",
"find_optional_toolchain",
"find_toolchain",
_name_to_crate_name = "name_to_crate_name",
)
Expand Down Expand Up @@ -315,14 +316,15 @@ def _cargo_build_script_impl(ctx):
"""
script = ctx.executable.script
script_info = ctx.attr.script[CargoBuildScriptRunfilesInfo]
toolchain = find_toolchain(ctx)
rustc_toolchain = find_toolchain(ctx)
cargo_toolchain = find_optional_toolchain(ctx, "@rust_toolchains//cargo:toolchain_type") or rustc_toolchain
out_dir = ctx.actions.declare_directory(ctx.label.name + ".out_dir")
env_out = ctx.actions.declare_file(ctx.label.name + ".env")
dep_env_out = ctx.actions.declare_file(ctx.label.name + ".depenv")
flags_out = ctx.actions.declare_file(ctx.label.name + ".flags")
link_flags = ctx.actions.declare_file(ctx.label.name + ".linkflags")
link_search_paths = ctx.actions.declare_file(ctx.label.name + ".linksearchpaths") # rustc-link-search, propagated from transitive dependencies
compilation_mode_opt_level = get_compilation_mode_opts(ctx, toolchain).opt_level
compilation_mode_opt_level = get_compilation_mode_opts(ctx, rustc_toolchain).opt_level

script_tools = []
script_data = []
Expand Down Expand Up @@ -364,7 +366,7 @@ def _cargo_build_script_impl(ctx):
if pkg_name == "":
pkg_name = name_to_pkg_name(ctx.label.name)

toolchain_tools = [toolchain.all_files]
toolchain_tools = [rustc_toolchain.all_files]

env = {}

Expand All @@ -380,19 +382,19 @@ def _cargo_build_script_impl(ctx):
if use_default_shell_env:
env.update(ctx.configuration.default_shell_env)

if toolchain.cargo:
env["CARGO"] = "${pwd}/%s" % toolchain.cargo.path
if cargo_toolchain.cargo:
env["CARGO"] = "${pwd}/%s" % cargo_toolchain.cargo.path

env.update({
"CARGO_CRATE_NAME": name_to_crate_name(pkg_name),
"CARGO_MANIFEST_DIR": manifest_dir,
"CARGO_PKG_NAME": pkg_name,
"HOST": toolchain.exec_triple.str,
"HOST": rustc_toolchain.exec_triple.str,
"NUM_JOBS": "1",
"OPT_LEVEL": compilation_mode_opt_level,
"RUSTC": toolchain.rustc.path,
"RUSTDOC": toolchain.rust_doc.path,
"TARGET": toolchain.target_flag_value,
"RUSTC": rustc_toolchain.rustc.path,
"RUSTDOC": rustc_toolchain.rust_doc.path,
"TARGET": rustc_toolchain.target_flag_value,
# OUT_DIR is set by the runner itself, rather than on the action.
})

Expand All @@ -414,7 +416,7 @@ def _cargo_build_script_impl(ctx):
# Pull in env vars which may be required for the cc_toolchain to work (e.g. on OSX, the SDK version).
# We hope that the linker env is sufficient for the whole cc_toolchain.
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
linker, _, link_args, linker_env = get_linker_and_args(ctx, "bin", toolchain, cc_toolchain, feature_configuration, None)
linker, _, link_args, linker_env = get_linker_and_args(ctx, "bin", rustc_toolchain, cc_toolchain, feature_configuration, None)
env.update(**linker_env)
env["LD"] = linker
env["LDFLAGS"] = " ".join(_pwd_flags(link_args))
Expand Down Expand Up @@ -477,7 +479,7 @@ def _cargo_build_script_impl(ctx):
# https://github.com/rust-lang/cargo/issues/9600
env["CARGO_ENCODED_RUSTFLAGS"] = "\\x1f".join([
# Allow build scripts to locate the generated sysroot
"--sysroot=${{pwd}}/{}".format(toolchain.sysroot),
"--sysroot=${{pwd}}/{}".format(rustc_toolchain.sysroot),
] + ctx.attr.rustc_flags)

for f in ctx.attr.crate_features:
Expand All @@ -488,7 +490,7 @@ def _cargo_build_script_impl(ctx):
env["CARGO_MANIFEST_LINKS"] = links

# Add environment variables from the Rust toolchain.
env.update(toolchain.env)
env.update(rustc_toolchain.env)

known_variables = {}

Expand Down Expand Up @@ -526,7 +528,7 @@ def _cargo_build_script_impl(ctx):
direct = [
script,
ctx.executable._cargo_build_script_runner,
] + fallback_tools + ([toolchain.target_json] if toolchain.target_json else []),
] + fallback_tools + ([rustc_toolchain.target_json] if rustc_toolchain.target_json else []),
transitive = script_data + script_tools + toolchain_tools,
)

Expand Down Expand Up @@ -772,7 +774,8 @@ cargo_build_script = rule(
},
fragments = ["cpp"],
toolchains = [
str(Label("//rust:toolchain_type")),
config_common.toolchain_type("@rust_toolchains//cargo:toolchain_type", mandatory = False),
str(Label("@rust_toolchains//rustc:toolchain_type")),
config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
],
)
Expand Down
7 changes: 5 additions & 2 deletions rust/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ exports_files([
"toolchain.bzl",
])

toolchain_type(
alias(
name = "toolchain_type",
actual = "@rust_toolchains//rustc:toolchain_type",
deprecation = "instead use `@rust_toolchains//rustc:toolchain_type`",
tags = ["manual"],
)

alias(
name = "toolchain",
actual = "toolchain_type",
deprecation = "instead use `@rules_rust//rust:toolchain_type`",
deprecation = "instead use `@rust_toolchains//rustc:toolchain_type`",
tags = ["manual"],
)

Expand Down
24 changes: 18 additions & 6 deletions rust/private/clippy.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ load(
"//rust/private:utils.bzl",
"determine_output_hash",
"find_cc_toolchain",
"find_optional_toolchain",
"find_toolchain",
)
load("//rust/settings:incompatible.bzl", "IncompatibleFlagInfo")
Expand Down Expand Up @@ -120,7 +121,16 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
Returns:
None
"""
toolchain = find_toolchain(ctx)
rustc_toolchain = find_toolchain(ctx)
rustc_toolchain_type = "@rust_toolchains//rustc:toolchain_type"

clippy_toolchain = find_optional_toolchain(ctx, "@rust_toolchains//clippy:toolchain_type")
if clippy_toolchain:
clippy_toolchain_type = "@rust_toolchains//clippy:toolchain_type"
else:
clippy_toolchain_type = rustc_toolchain_type
clippy_toolchain = rustc_toolchain

cc_toolchain, feature_configuration = find_cc_toolchain(ctx)

dep_info, build_info, _ = collect_deps(
Expand All @@ -146,7 +156,7 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
ctx.rule.files,
# Clippy doesn't need to invoke transitive linking, therefore doesn't need linkstamps.
depset([]),
toolchain,
rustc_toolchain,
cc_toolchain,
feature_configuration,
crate_info,
Expand All @@ -164,7 +174,7 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
ctx = ctx,
attr = ctx.rule.attr,
file = ctx.file,
toolchain = toolchain,
toolchain = rustc_toolchain,
tool_path = clippy_executable.path,
cc_toolchain = cc_toolchain,
feature_configuration = feature_configuration,
Expand Down Expand Up @@ -232,7 +242,7 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
arguments = args.all,
mnemonic = "Clippy",
progress_message = "Clippy %{label}",
toolchain = "@rules_rust//rust:toolchain_type",
toolchain = clippy_toolchain_type,
)

def _clippy_aspect_impl(target, ctx):
Expand All @@ -246,7 +256,8 @@ def _clippy_aspect_impl(target, ctx):
if not crate_info:
return [ClippyInfo(output = depset([]))]

toolchain = find_toolchain(ctx)
clippy_toolchain = find_optional_toolchain(ctx, "@rust_toolchains//clippy:toolchain_type") or find_toolchain(ctx)
toolchain = clippy_toolchain or find_toolchain(ctx)

# For remote execution purposes, the clippy_out file must be a sibling of crate_info.output
# or rustc may fail to create intermediate output files because the directory does not exist.
Expand Down Expand Up @@ -359,7 +370,8 @@ rust_clippy_aspect = aspect(
[rust_common.test_crate_info],
],
toolchains = [
str(Label("//rust:toolchain_type")),
config_common.toolchain_type("@rust_toolchains//clippy:toolchain_type", mandatory = False),
str(Label("@rust_toolchains//rustc:toolchain_type")),
config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
],
implementation = _clippy_aspect_impl,
Expand Down
26 changes: 21 additions & 5 deletions rust/private/toolchain_utils.bzl
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
"""A module defining toolchain utilities"""
"""A module defining toolchain utilities."""

def _find_rustc_toolchain(ctx):
return ctx.toolchains[str(Label("@rust_toolchains//rustc:toolchain_type"))]

def _toolchain_files_impl(ctx):
toolchain = ctx.toolchains[str(Label("//rust:toolchain_type"))]
rustc_toolchain = _find_rustc_toolchain(ctx)
clippy_toolchain_label = str(Label("@rust_toolchains//clippy:toolchain_type"))
clippy_toolchain = ctx.toolchains[clippy_toolchain_label] if clippy_toolchain_label in ctx.toolchains else None
cargo_toolchain_label = str(Label("@rust_toolchains//cargo:toolchain_type"))
cargo_toolchain = ctx.toolchains[cargo_toolchain_label] if cargo_toolchain_label in ctx.toolchains else None

if ctx.attr.tool == "clippy" or ctx.attr.tool == "cargo-clippy":
toolchain = clippy_toolchain or rustc_toolchain
elif ctx.attr.tool == "cargo":
toolchain = cargo_toolchain or rustc_toolchain
else:
toolchain = rustc_toolchain

runfiles = None
if ctx.attr.tool == "cargo":
Expand Down Expand Up @@ -84,12 +98,14 @@ toolchain_files = rule(
),
},
toolchains = [
str(Label("//rust:toolchain_type")),
str(Label("@rust_toolchains//rustc:toolchain_type")),
config_common.toolchain_type("@rust_toolchains//clippy:toolchain_type", mandatory = False),
config_common.toolchain_type("@rust_toolchains//cargo:toolchain_type", mandatory = False),
],
)

def _current_rust_toolchain_impl(ctx):
toolchain = ctx.toolchains[str(Label("@rules_rust//rust:toolchain_type"))]
toolchain = _find_rustc_toolchain(ctx)

return [
toolchain,
Expand All @@ -103,7 +119,7 @@ current_rust_toolchain = rule(
doc = "A rule for exposing the current registered `rust_toolchain`.",
implementation = _current_rust_toolchain_impl,
toolchains = [
str(Label("@rules_rust//rust:toolchain_type")),
str(Label("@rust_toolchains//rustc:toolchain_type")),
],
)

Expand Down
33 changes: 30 additions & 3 deletions rust/private/utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,42 @@ def parse_env_strings(entries):
return env_vars

def find_toolchain(ctx):
"""Finds the first rust toolchain that is configured.
"""Finds the first rustc toolchain that is configured.
Args:
ctx (ctx): The ctx object for the current target.
Returns:
rust_toolchain: A Rust toolchain context.
rust_toolchain: A Rustc toolchain context.
"""
return ctx.toolchains[Label("//rust:toolchain_type")]
rustc_toolchain_type = str(Label("@rust_toolchains//rustc:toolchain_type"))
if rustc_toolchain_type in ctx.toolchains:
return ctx.toolchains[rustc_toolchain_type]

# Keep compatibility for rules that still request the legacy type label.
legacy_toolchain_type = str(Label("//rust:toolchain_type"))
if legacy_toolchain_type in ctx.toolchains:
return ctx.toolchains[legacy_toolchain_type]

fail(
"No Rust toolchain configured. Expected @rust_toolchains//rustc:toolchain_type " +
"or //rust:toolchain_type.",
)

def find_optional_toolchain(ctx, toolchain_type):
"""Finds the configured toolchain for a given type if it exists.
Args:
ctx (ctx): The ctx object for the current target.
toolchain_type (str): The toolchain type label.
Returns:
rust_toolchain or None: The toolchain context or None if unavailable.
"""
toolchain_label = str(Label(toolchain_type))
if toolchain_label in ctx.toolchains:
return ctx.toolchains[toolchain_label]
return None

# A global kill switch to test without a cc toolchain present.
_FORCE_DISABLE_CC_TOOLCHAIN = False
Expand Down
5 changes: 4 additions & 1 deletion rust/rust_analyzer/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package(default_visibility = ["//visibility:public"])

toolchain_type(
alias(
name = "toolchain_type",
actual = "@rust_toolchains//rust_analyzer:toolchain_type",
deprecation = "instead use `@rust_toolchains//rust_analyzer:toolchain_type`",
tags = ["manual"],
)
5 changes: 4 additions & 1 deletion rust/rustfmt/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package(default_visibility = ["//visibility:public"])

toolchain_type(
alias(
name = "toolchain_type",
actual = "@rust_toolchains//rustfmt:toolchain_type",
deprecation = "instead use `@rust_toolchains//rustfmt:toolchain_type`",
tags = ["manual"],
)
1 change: 1 addition & 0 deletions rust_toolchains/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package(default_visibility = ["//visibility:public"])
4 changes: 4 additions & 0 deletions rust_toolchains/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module(
name = "rust_toolchains",
version = "0.0.1",
)
6 changes: 6 additions & 0 deletions rust_toolchains/cargo/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package(default_visibility = ["//visibility:public"])

# The toolchain for the exec platform.
toolchain_type(
name = "toolchain_type",
)
6 changes: 6 additions & 0 deletions rust_toolchains/clippy/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package(default_visibility = ["//visibility:public"])

# The toolchain for the exec platform.
toolchain_type(
name = "toolchain_type",
)
6 changes: 6 additions & 0 deletions rust_toolchains/rust_analyzer/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package(default_visibility = ["//visibility:public"])

# The toolchain for the exec platform.
toolchain_type(
name = "toolchain_type",
)
6 changes: 6 additions & 0 deletions rust_toolchains/rustc/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package(default_visibility = ["//visibility:public"])

# The toolchain for the exec platform.
toolchain_type(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we comment explicitly that these are all meant to resolve to the exec platform? I dunno why it would be useful to have target-platform for these tools but I can imagine the feature request

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, we can :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I can imagine a scenario where your target platform is meant for execution. Imagine you are building dev VM images or similar and want to package a compiler.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and you could also have clippy run as a test, and use target platform for tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get this landed first to unblock progress and then we can do target-platform toolchains as a followup

name = "toolchain_type",
)
6 changes: 6 additions & 0 deletions rust_toolchains/rustfmt/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package(default_visibility = ["//visibility:public"])

# The toolchain for the exec platform.
toolchain_type(
name = "toolchain_type",
)
Loading
Loading