diff --git a/MODULE.bazel b/MODULE.bazel index 3dae74cc76..835fad8b56 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -12,10 +12,16 @@ 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") 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( @@ -45,10 +51,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") diff --git a/cargo/private/cargo_build_script.bzl b/cargo/private/cargo_build_script.bzl index ae79b7fdd6..672633288d 100644 --- a/cargo/private/cargo_build_script.bzl +++ b/cargo/private/cargo_build_script.bzl @@ -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", ) @@ -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 = [] @@ -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 = {} @@ -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. }) @@ -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)) @@ -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: @@ -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 = {} @@ -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, ) @@ -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), ], ) diff --git a/rust/BUILD.bazel b/rust/BUILD.bazel index f4edbd8b61..1103998d07 100644 --- a/rust/BUILD.bazel +++ b/rust/BUILD.bazel @@ -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"], ) diff --git a/rust/private/clippy.bzl b/rust/private/clippy.bzl index 318c05af8d..efb67ca7ee 100644 --- a/rust/private/clippy.bzl +++ b/rust/private/clippy.bzl @@ -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") @@ -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( @@ -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, @@ -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, @@ -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): @@ -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. @@ -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, diff --git a/rust/private/toolchain_utils.bzl b/rust/private/toolchain_utils.bzl index 078e6f34c3..c7f653e5e4 100644 --- a/rust/private/toolchain_utils.bzl +++ b/rust/private/toolchain_utils.bzl @@ -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": @@ -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, @@ -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")), ], ) diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl index 8a82126d53..f92aa3b09f 100644 --- a/rust/private/utils.bzl +++ b/rust/private/utils.bzl @@ -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 diff --git a/rust/rust_analyzer/BUILD.bazel b/rust/rust_analyzer/BUILD.bazel index 04e6c60d79..e84944f090 100644 --- a/rust/rust_analyzer/BUILD.bazel +++ b/rust/rust_analyzer/BUILD.bazel @@ -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"], ) diff --git a/rust/rustfmt/BUILD.bazel b/rust/rustfmt/BUILD.bazel index 04e6c60d79..122b72ede9 100644 --- a/rust/rustfmt/BUILD.bazel +++ b/rust/rustfmt/BUILD.bazel @@ -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"], ) diff --git a/rust_toolchains/BUILD.bazel b/rust_toolchains/BUILD.bazel new file mode 100644 index 0000000000..ffd0fb0cdc --- /dev/null +++ b/rust_toolchains/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/rust_toolchains/MODULE.bazel b/rust_toolchains/MODULE.bazel new file mode 100644 index 0000000000..9078118d97 --- /dev/null +++ b/rust_toolchains/MODULE.bazel @@ -0,0 +1,4 @@ +module( + name = "rust_toolchains", + version = "0.0.1", +) diff --git a/rust_toolchains/cargo/BUILD.bazel b/rust_toolchains/cargo/BUILD.bazel new file mode 100644 index 0000000000..ad29cb37a2 --- /dev/null +++ b/rust_toolchains/cargo/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +# The toolchain for the exec platform. +toolchain_type( + name = "toolchain_type", +) diff --git a/rust_toolchains/clippy/BUILD.bazel b/rust_toolchains/clippy/BUILD.bazel new file mode 100644 index 0000000000..ad29cb37a2 --- /dev/null +++ b/rust_toolchains/clippy/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +# The toolchain for the exec platform. +toolchain_type( + name = "toolchain_type", +) diff --git a/rust_toolchains/rust_analyzer/BUILD.bazel b/rust_toolchains/rust_analyzer/BUILD.bazel new file mode 100644 index 0000000000..ad29cb37a2 --- /dev/null +++ b/rust_toolchains/rust_analyzer/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +# The toolchain for the exec platform. +toolchain_type( + name = "toolchain_type", +) diff --git a/rust_toolchains/rustc/BUILD.bazel b/rust_toolchains/rustc/BUILD.bazel new file mode 100644 index 0000000000..ad29cb37a2 --- /dev/null +++ b/rust_toolchains/rustc/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +# The toolchain for the exec platform. +toolchain_type( + name = "toolchain_type", +) diff --git a/rust_toolchains/rustfmt/BUILD.bazel b/rust_toolchains/rustfmt/BUILD.bazel new file mode 100644 index 0000000000..ad29cb37a2 --- /dev/null +++ b/rust_toolchains/rustfmt/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +# The toolchain for the exec platform. +toolchain_type( + name = "toolchain_type", +) diff --git a/rust_toolchains/toolchain/BUILD.bazel b/rust_toolchains/toolchain/BUILD.bazel new file mode 100644 index 0000000000..fb71cf9b11 --- /dev/null +++ b/rust_toolchains/toolchain/BUILD.bazel @@ -0,0 +1,77 @@ +load( + "@rules_rust//rust:toolchain.bzl", + "current_rust_analyzer_toolchain", + "current_rustfmt_toolchain", +) + +# This module is a child of rules_rust so we permit "friendly" visibility +# buildifier: disable=bzl-visibility +load( + "@rules_rust//rust/private:toolchain_utils.bzl", + "current_rust_toolchain", + "toolchain_files", + "toolchain_files_for_target", +) + +package(default_visibility = ["//visibility:public"]) + +toolchain_files( + name = "current_cargo_files", + tool = "cargo", +) + +toolchain_files( + name = "current_clippy_files", + tool = "clippy", +) + +toolchain_files( + name = "current_cargo_clippy_files", + tool = "cargo-clippy", +) + +toolchain_files( + name = "current_rustc_files", + tool = "rustc", +) + +toolchain_files( + name = "current_rustdoc_files", + tool = "rustdoc", +) + +toolchain_files( + name = "current_rustc_lib_files", + tool = "rustc_lib", +) + +toolchain_files( + name = "current_rust_stdlib_files", + tool = "rust_stdlib", +) + +current_rust_toolchain( + name = "current_rust_toolchain", +) + +current_rustfmt_toolchain( + name = "current_rustfmt_toolchain", +) + +current_rust_analyzer_toolchain( + name = "current_rust_analyzer_toolchain", + tags = ["manual"], +) + +toolchain_files_for_target( + name = "current_rustfmt_toolchain_for_target", + toolchain_files = ":current_rustfmt_toolchain", + visibility = ["//:__subpackages__"], +) + +alias( + name = "current_rustfmt_files", + actual = ":current_rustfmt_toolchain", + deprecation = "instead use `@rules_rust//rust/toolchain:current_rustfmt_toolchain`", + tags = ["manual"], +)