diff --git a/docs/src/flatten.md b/docs/src/flatten.md index 88d5319777..4632cb0feb 100644 --- a/docs/src/flatten.md +++ b/docs/src/flatten.md @@ -1363,7 +1363,8 @@ str: The name of a registerable rust_analyzer_toolchain. rust_register_toolchains(dev_components, edition, allocator_library, global_allocator_library, register_toolchains, rustfmt_version, rust_analyzer_version, sha256s, extra_target_triples, extra_rustc_flags, extra_exec_rustc_flags, urls, - versions, aliases, hub_name, compact_windows_names) + versions, aliases, hub_name, compact_windows_names, toolchain_triples, + rustfmt_toolchain_triples, extra_toolchain_infos) Emits a default set of toolchains for Linux, MacOS, and Freebsd @@ -1404,6 +1405,9 @@ See `load_arbitrary_tool` in `@rules_rust//rust:repositories.bzl` for more detai | aliases | A mapping of "full" repository name to another name to use instead. | `{}` | | hub_name | The name of the bzlmod hub repository for toolchains. | `None` | | compact_windows_names | Whether or not to produce compact repository names for windows toolchains. This is to avoid MAX_PATH issues. | `True` | +| toolchain_triples | Mapping of rust target triple -> repository name to create. | `{"aarch64-apple-darwin": "rust_darwin_aarch64", "aarch64-pc-windows-msvc": "rust_windows_aarch64", "aarch64-unknown-linux-gnu": "rust_linux_aarch64", "s390x-unknown-linux-gnu": "rust_linux_s390x", "x86_64-apple-darwin": "rust_darwin_x86_64", "x86_64-pc-windows-msvc": "rust_windows_x86_64", "x86_64-unknown-freebsd": "rust_freebsd_x86_64", "x86_64-unknown-linux-gnu": "rust_linux_x86_64"}` | +| rustfmt_toolchain_triples | Like toolchain_triples, but for rustfmt toolchains. | `{"aarch64-apple-darwin": "rust_darwin_aarch64", "aarch64-pc-windows-msvc": "rust_windows_aarch64", "aarch64-unknown-linux-gnu": "rust_linux_aarch64", "s390x-unknown-linux-gnu": "rust_linux_s390x", "x86_64-apple-darwin": "rust_darwin_x86_64", "x86_64-pc-windows-msvc": "rust_windows_x86_64", "x86_64-unknown-freebsd": "rust_freebsd_x86_64", "x86_64-unknown-linux-gnu": "rust_linux_x86_64"}` | +| extra_toolchain_infos | (dict[str, dict], optional): Mapping of information about extra toolchains which were created outside of this call, which should be added to the hub repo. | `None` | @@ -1467,6 +1471,10 @@ Assembles a remote repository for the given toolchain params, produces a proxy r | aliases | Replacement names to use for toolchains created by this macro. | `{}` | | compact_windows_names | Whether or not to produce compact repository names for windows toolchains. This is to avoid MAX_PATH issues. | `True` | +**RETURNS** + +dict[str, dict]: A dict of informations about all generated toolchains. + @@ -1579,7 +1587,7 @@ Assembles a remote repository for the given toolchain params, produces a proxy r **RETURNS** -str: The name of the registerable toolchain created by this rule. +dict[str, str]: Information about the registerable toolchain created by this rule. diff --git a/docs/src/rust_repositories.md b/docs/src/rust_repositories.md index c3c259e434..fa0d0318d4 100644 --- a/docs/src/rust_repositories.md +++ b/docs/src/rust_repositories.md @@ -177,7 +177,8 @@ str: The name of a registerable rust_analyzer_toolchain. rust_register_toolchains(dev_components, edition, allocator_library, global_allocator_library, register_toolchains, rustfmt_version, rust_analyzer_version, sha256s, extra_target_triples, extra_rustc_flags, extra_exec_rustc_flags, urls, - versions, aliases, hub_name, compact_windows_names) + versions, aliases, hub_name, compact_windows_names, toolchain_triples, + rustfmt_toolchain_triples, extra_toolchain_infos) Emits a default set of toolchains for Linux, MacOS, and Freebsd @@ -218,6 +219,9 @@ See `load_arbitrary_tool` in `@rules_rust//rust:repositories.bzl` for more detai | aliases | A mapping of "full" repository name to another name to use instead. | `{}` | | hub_name | The name of the bzlmod hub repository for toolchains. | `None` | | compact_windows_names | Whether or not to produce compact repository names for windows toolchains. This is to avoid MAX_PATH issues. | `True` | +| toolchain_triples | Mapping of rust target triple -> repository name to create. | `{"aarch64-apple-darwin": "rust_darwin_aarch64", "aarch64-pc-windows-msvc": "rust_windows_aarch64", "aarch64-unknown-linux-gnu": "rust_linux_aarch64", "s390x-unknown-linux-gnu": "rust_linux_s390x", "x86_64-apple-darwin": "rust_darwin_x86_64", "x86_64-pc-windows-msvc": "rust_windows_x86_64", "x86_64-unknown-freebsd": "rust_freebsd_x86_64", "x86_64-unknown-linux-gnu": "rust_linux_x86_64"}` | +| rustfmt_toolchain_triples | Like toolchain_triples, but for rustfmt toolchains. | `{"aarch64-apple-darwin": "rust_darwin_aarch64", "aarch64-pc-windows-msvc": "rust_windows_aarch64", "aarch64-unknown-linux-gnu": "rust_linux_aarch64", "s390x-unknown-linux-gnu": "rust_linux_s390x", "x86_64-apple-darwin": "rust_darwin_x86_64", "x86_64-pc-windows-msvc": "rust_windows_x86_64", "x86_64-unknown-freebsd": "rust_freebsd_x86_64", "x86_64-unknown-linux-gnu": "rust_linux_x86_64"}` | +| extra_toolchain_infos | (dict[str, dict], optional): Mapping of information about extra toolchains which were created outside of this call, which should be added to the hub repo. | `None` | @@ -281,6 +285,10 @@ Assembles a remote repository for the given toolchain params, produces a proxy r | aliases | Replacement names to use for toolchains created by this macro. | `{}` | | compact_windows_names | Whether or not to produce compact repository names for windows toolchains. This is to avoid MAX_PATH issues. | `True` | +**RETURNS** + +dict[str, dict]: A dict of informations about all generated toolchains. + @@ -325,7 +333,7 @@ Assembles a remote repository for the given toolchain params, produces a proxy r **RETURNS** -str: The name of the registerable toolchain created by this rule. +dict[str, str]: Information about the registerable toolchain created by this rule. diff --git a/examples/musl_cross_compiling/MODULE.bazel b/examples/musl_cross_compiling/MODULE.bazel index 00bb18361f..4dfd688899 100644 --- a/examples/musl_cross_compiling/MODULE.bazel +++ b/examples/musl_cross_compiling/MODULE.bazel @@ -1,6 +1,137 @@ -############################################################################### -# Bazel now uses Bzlmod by default to manage external dependencies. -# Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel. -# -# For more details, please check https://github.com/bazelbuild/bazel/issues/18958 -############################################################################### +module( + name = "musl_cross_compiling_example", + version = "0.0.0", +) + +bazel_dep( + name = "rules_rust", + version = "0.0.0", +) +local_path_override( + module_name = "rules_rust", + path = "../..", +) + +bazel_dep( + name = "platforms", + version = "0.0.10", +) +bazel_dep( + name = "rules_shell", + version = "0.3.0", +) + +RUST_EDITION = "2021" + +RUST_VERSION = "1.80.0" + +rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") +rust.toolchain( + edition = RUST_EDITION, + versions = [RUST_VERSION], +) + +# This overrides a default rust_repository_set created by rust_register_toolchain. +# It must be named exactly this. +# Each exec triple needs one of these calls per target triple it supports. +# The first call needs all of the attrs, the subsequent calls should only set name, target_triple, and target_compatible_with. +rust.repository_set( + name = "rust_linux_x86_64", + edition = RUST_EDITION, + exec_triple = "x86_64-unknown-linux-gnu", + target_compatible_with = [ + "@//linker_config:unknown", + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_triple = "x86_64-unknown-linux-gnu", + versions = [RUST_VERSION], +) +rust.repository_set( + name = "rust_linux_x86_64", + target_compatible_with = [ + "@//linker_config:musl", + "@platforms//cpu:arm64", + "@platforms//os:linux", + ], + target_triple = "aarch64-unknown-linux-musl", +) +rust.repository_set( + name = "rust_linux_x86_64", + target_compatible_with = [ + "@//linker_config:musl", + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_triple = "x86_64-unknown-linux-musl", +) + +# We don't need to register a repository_set for exec_triple == target_triple if we're not customising it in any way: +# one will get registered by default. +# But we do for the Linux case above, because we want to add the "@//linker_config:unknown" constraint in that case. +rust.repository_set( + name = "rust_darwin_x86_64", + edition = RUST_EDITION, + exec_triple = "x86_64-apple-darwin", + target_compatible_with = [ + "@//linker_config:musl", + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_triple = "x86_64-unknown-linux-musl", + versions = [RUST_VERSION], +) +rust.repository_set( + name = "rust_darwin_x86_64", + target_compatible_with = [ + "@//linker_config:musl", + "@platforms//cpu:arm64", + "@platforms//os:linux", + ], + target_triple = "aarch64-unknown-linux-musl", +) +rust.repository_set( + name = "rust_darwin_aarch64", + edition = RUST_EDITION, + exec_triple = "aarch64-apple-darwin", + target_compatible_with = [ + "@//linker_config:musl", + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_triple = "x86_64-unknown-linux-musl", + versions = [RUST_VERSION], +) +rust.repository_set( + name = "rust_darwin_aarch64", + target_compatible_with = [ + "@//linker_config:musl", + "@platforms//cpu:arm64", + "@platforms//os:linux", + ], + target_triple = "aarch64-unknown-linux-musl", +) +use_repo(rust, "rust_toolchains") + +register_toolchains("@rust_toolchains//:all") + +crate = use_extension( + "@rules_rust//crate_universe:extensions.bzl", + "crate", +) +crate.from_cargo( + name = "cu", + cargo_lockfile = "//:Cargo.Bazel.lock", + manifests = [ + "//:Cargo.toml", + "//:local_proc_macro/Cargo.toml", + ], +) +use_repo(crate, "cu") + +bazel_dep(name = "toolchains_musl", version = "0.1.20", dev_dependency = True) + +toolchains_musl = use_extension("@toolchains_musl//:toolchains_musl.bzl", "toolchains_musl", dev_dependency = True) +toolchains_musl.config( + extra_target_compatible_with = ["@//linker_config:musl"], +) diff --git a/examples/musl_cross_compiling/WORKSPACE.bazel b/examples/musl_cross_compiling/WORKSPACE.bazel index c12fc4c4f9..e69de29bb2 100644 --- a/examples/musl_cross_compiling/WORKSPACE.bazel +++ b/examples/musl_cross_compiling/WORKSPACE.bazel @@ -1,143 +0,0 @@ -local_repository( - name = "rules_rust", - path = "../..", -) - -load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains", "rust_repository_set") - -rules_rust_dependencies() - -EDITION = "2021" - -# Before 1.80.0, proc macros couldn't be used when exec!=target where exec and target platforms use different shared library extension (i.e. so vs dylib) because of an error in rustc's handling of extensions. -RUST_VERSION = "1.80.0" - -rust_repository_set( - name = "darwin_x86_64_to_x86_64_musl_tuple", - edition = EDITION, - exec_triple = "x86_64-apple-darwin", - # Setting this extra_target_triples allows differentiating the musl case from the non-musl case, in case multiple linux-targeting toolchains are registered. - extra_target_triples = { - "x86_64-unknown-linux-musl": [ - "@//linker_config:musl", - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], - }, - versions = [RUST_VERSION], -) - -rust_repository_set( - name = "darwin_arm64_to_x86_64_musl_tuple", - edition = EDITION, - exec_triple = "aarch64-apple-darwin", - extra_target_triples = { - "x86_64-unknown-linux-musl": [ - "@//linker_config:musl", - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], - }, - versions = [RUST_VERSION], -) - -rust_repository_set( - name = "darwin_x86_64_to_arm64_musl_tuple", - edition = EDITION, - exec_triple = "x86_64-apple-darwin", - # Setting this extra_target_triples allows differentiating the musl case from the non-musl case, in case multiple linux-targeting toolchains are registered. - extra_target_triples = { - "aarch64-unknown-linux-musl": [ - "@//linker_config:musl", - "@platforms//cpu:arm64", - "@platforms//os:linux", - ], - }, - versions = [RUST_VERSION], -) - -rust_repository_set( - name = "darwin_arm64_to_arm64_musl_tuple", - edition = EDITION, - exec_triple = "aarch64-apple-darwin", - extra_target_triples = { - "aarch64-unknown-linux-musl": [ - "@//linker_config:musl", - "@platforms//cpu:arm64", - "@platforms//os:linux", - ], - }, - versions = [RUST_VERSION], -) - -# This overrides a default rust_repository_set created by rust_register_toolchain. -# It must be named exactly this, and must be called before rust_register_toolchain is. -rust_repository_set( - name = "rust_linux_x86_64", - edition = EDITION, - exec_triple = "x86_64-unknown-linux-gnu", - # Setting this extra_target_triples allows differentiating the musl case from the non-musl case, in case multiple linux-targeting toolchains are registered. - extra_target_triples = { - "aarch64-unknown-linux-musl": [ - "@//linker_config:musl", - "@platforms//cpu:arm64", - "@platforms//os:linux", - ], - "x86_64-unknown-linux-gnu": [ - "@//linker_config:unknown", - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], - "x86_64-unknown-linux-musl": [ - "@//linker_config:musl", - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], - }, - versions = [RUST_VERSION], -) - -rust_register_toolchains( - edition = EDITION, - versions = [RUST_VERSION], -) - -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "musl_toolchains", - sha256 = "1e6cf99f35277dbb9c3b341a9986d0f33cf70e0cc76a58f062d2d9b7ab56eeeb", - url = "https://github.com/bazel-contrib/musl-toolchain/releases/download/v0.1.17/musl_toolchain-v0.1.17.tar.gz", -) - -load("@musl_toolchains//:repositories.bzl", "load_musl_toolchains") - -# Setting this extra_target_triples allows differentiating the musl case from the non-musl case, in case multiple linux-targeting toolchains are registered. -load_musl_toolchains(extra_target_compatible_with = ["@//linker_config:musl"]) - -load("@musl_toolchains//:toolchains.bzl", "register_musl_toolchains") - -register_musl_toolchains() - -load("@rules_rust//crate_universe:repositories.bzl", "crate_universe_dependencies") - -crate_universe_dependencies(bootstrap = True) - -load("@rules_rust//crate_universe:defs.bzl", "crates_repository") - -crates_repository( - name = "cu", - cargo_lockfile = "//:Cargo.Bazel.lock", - # `generator` is not necessary in official releases. - # See load statement for `cargo_bazel_bootstrap`. - generator = "@cargo_bazel_bootstrap//:cargo-bazel", - lockfile = "//:Cargo.Bazel.lock.json", - manifests = [ - "//:Cargo.toml", - "//:local_proc_macro/Cargo.toml", - ], -) - -load("@cu//:defs.bzl", "crate_repositories") - -crate_repositories() diff --git a/rust/extensions.bzl b/rust/extensions.bzl index 61dd9fd096..ac3fc8f6b7 100644 --- a/rust/extensions.bzl +++ b/rust/extensions.bzl @@ -2,7 +2,7 @@ load("@bazel_features//:features.bzl", "bazel_features") load("//rust:defs.bzl", "rust_common") -load("//rust:repositories.bzl", "rust_register_toolchains", "rust_toolchain_tools_repository") +load("//rust:repositories.bzl", "DEFAULT_TOOLCHAIN_TRIPLES", "rust_register_toolchains", "rust_repository_set", "rust_toolchain_tools_repository") load("//rust/platform:triple.bzl", "get_host_triple") load( "//rust/private:repository_utils.bzl", @@ -48,6 +48,47 @@ def _rust_impl(module_ctx): # See https://github.com/bazelbuild/bazel/discussions/22024 for discussion. root, rules_rust = _find_modules(module_ctx) + toolchain_triples = dict(DEFAULT_TOOLCHAIN_TRIPLES) + + repository_sets = root.tags.repository_set + + grouped_repository_sets = {} + for repository_set in repository_sets: + if repository_set.name not in grouped_repository_sets: + grouped_repository_sets[repository_set.name] = { + "allocator_library": repository_set.allocator_library, + "dev_components": repository_set.dev_components, + "edition": repository_set.edition, + "exec_triple": repository_set.exec_triple, + "extra_target_triples": {repository_set.target_triple: [str(v) for v in repository_set.target_compatible_with]}, + "name": repository_set.name, + "rustfmt_version": repository_set.rustfmt_version, + "sha256s": repository_set.sha256s, + "urls": repository_set.urls, + "versions": repository_set.versions, + } + else: + for attr_name in _RUST_REPOSITORY_SET_TAG_ATTRS.keys(): + if attr_name in ["extra_target_triples", "name", "target_compatible_with", "target_triple"]: + continue + attr_value = getattr(repository_set, attr_name, None) + if attr_value: + default_value = _COMMON_TAG_DEFAULTS.get(attr_name, None) + if not default_value or attr_value != default_value: + fail("You must only set {} on the first call to repository_set for a particular name but it was set multiple times for {}".format(attr_name, repository_set.name)) + grouped_repository_sets[repository_set.name]["extra_target_triples"][repository_set.target_triple] = [str(v) for v in repository_set.target_compatible_with] + + extra_toolchain_infos = {} + + for repository_set in grouped_repository_sets.values(): + toolchain_infos = rust_repository_set( + register_toolchain = False, + **repository_set + ) + extra_toolchain_infos.update(**toolchain_infos) + if toolchain_triples.get(repository_set["exec_triple"]) == repository_set["name"]: + toolchain_triples.pop(repository_set["exec_triple"], None) + toolchains = root.tags.toolchain or rules_rust.tags.toolchain for toolchain in toolchains: @@ -77,16 +118,24 @@ def _rust_impl(module_ctx): versions = toolchain.versions, register_toolchains = False, aliases = toolchain.aliases, + toolchain_triples = toolchain_triples, + extra_toolchain_infos = extra_toolchain_infos, ) metadata_kwargs = {} if bazel_features.external_deps.extension_metadata_has_reproducible: metadata_kwargs["reproducible"] = True return module_ctx.extension_metadata(**metadata_kwargs) +_COMMON_TAG_DEFAULTS = { + "allocator_library": "@rules_rust//ffi/cc/allocator_library", + "rustfmt_version": DEFAULT_NIGHTLY_VERSION, + "urls": DEFAULT_STATIC_RUST_URL_TEMPLATES, +} + _COMMON_TAG_KWARGS = { "allocator_library": attr.string( doc = "Target that provides allocator functions when rust_library targets are embedded in a cc_binary.", - default = "@rules_rust//ffi/cc/allocator_library", + default = _COMMON_TAG_DEFAULTS["allocator_library"], ), "dev_components": attr.bool( doc = "Whether to download the rustc-dev components (defaults to False). Requires version to be \"nightly\".", @@ -100,17 +149,35 @@ _COMMON_TAG_KWARGS = { ), "rustfmt_version": attr.string( doc = "The version of the tool among \"nightly\", \"beta\", or an exact version.", - default = DEFAULT_NIGHTLY_VERSION, + default = _COMMON_TAG_DEFAULTS["rustfmt_version"], ), "sha256s": attr.string_dict( doc = "A dict associating tool subdirectories to sha256 hashes. See [rust_repositories](#rust_repositories) for more details.", ), "urls": attr.string_list( doc = "A list of mirror urls containing the tools from the Rust-lang static file server. These must contain the '{}' used to substitute the tool being fetched (using .format).", - default = DEFAULT_STATIC_RUST_URL_TEMPLATES, + default = _COMMON_TAG_DEFAULTS["urls"], ), } +_RUST_REPOSITORY_SET_TAG_ATTRS = { + "exec_triple": attr.string(doc = "Exec triple for this repository_set."), + "name": attr.string(doc = "Name of the repository_set - if you're looking to replace default toolchains you must use the exact name you're replacing."), + "target_compatible_with": attr.label_list(doc = "List of platform constraints this toolchain produces, for the particular target_triple this call is for."), + "target_triple": attr.string(doc = "target_triple to configure."), + "versions": attr.string_list( + doc = ( + "A list of toolchain versions to download. This parameter only accepts one version " + + "per channel. E.g. `[\"1.65.0\", \"nightly/2022-11-02\", \"beta/2020-12-30\"]`. " + + "May be set to an empty list (`[]`) to inhibit `rules_rust` from registering toolchains." + ), + ), +} | _COMMON_TAG_KWARGS + +_RUST_REPOSITORY_SET_TAG = tag_class( + attrs = _RUST_REPOSITORY_SET_TAG_ATTRS, +) + _RUST_TOOLCHAIN_TAG = tag_class( attrs = { "aliases": attr.string_dict( @@ -161,6 +228,7 @@ rust = module_extension( doc = "Rust toolchain extension.", implementation = _rust_impl, tag_classes = { + "repository_set": _RUST_REPOSITORY_SET_TAG, "toolchain": _RUST_TOOLCHAIN_TAG, }, ) diff --git a/rust/repositories.bzl b/rust/repositories.bzl index f158f4bb61..06de237d54 100644 --- a/rust/repositories.bzl +++ b/rust/repositories.bzl @@ -152,7 +152,10 @@ def rust_register_toolchains( versions = _RUST_TOOLCHAIN_VERSIONS, aliases = {}, hub_name = None, - compact_windows_names = _COMPACT_WINDOWS_NAMES): + compact_windows_names = _COMPACT_WINDOWS_NAMES, + toolchain_triples = DEFAULT_TOOLCHAIN_TRIPLES, + rustfmt_toolchain_triples = DEFAULT_TOOLCHAIN_TRIPLES, + extra_toolchain_infos = None): """Emits a default set of toolchains for Linux, MacOS, and Freebsd Skip this macro and call the `rust_repository_set` macros directly if you need a compiler for \ @@ -190,6 +193,9 @@ def rust_register_toolchains( hub_name (str, optional): The name of the bzlmod hub repository for toolchains. compact_windows_names (bool): Whether or not to produce compact repository names for windows toolchains. This is to avoid MAX_PATH issues. + toolchain_triples (dict[str, str], optional): Mapping of rust target triple -> repository name to create. + rustfmt_toolchain_triples (dict[str, str], optional): Like toolchain_triples, but for rustfmt toolchains. + extra_toolchain_infos: (dict[str, dict], optional): Mapping of information about extra toolchains which were created outside of this call, which should be added to the hub repo. """ if not rustfmt_version: if len(versions) == 1: @@ -243,7 +249,7 @@ def rust_register_toolchains( rust_analyzer_repo_name, )) - for exec_triple, name in DEFAULT_TOOLCHAIN_TRIPLES.items(): + for exec_triple, name in toolchain_triples.items(): maybe( rust_repository_set, name = name, @@ -263,6 +269,23 @@ def rust_register_toolchains( aliases = aliases, ) + for toolchain in _get_toolchain_repositories( + name = name, + exec_triple = exec_triple, + extra_target_triples = extra_target_triples, + versions = versions, + fallback_target_compatible_with = None, + aliases = aliases, + compact_windows_names = compact_windows_names, + ): + toolchain_names.append(toolchain.name) + toolchain_labels[toolchain.name] = "@{}//:{}".format(toolchain.name + "_tools", "rust_toolchain") + exec_compatible_with_by_toolchain[toolchain.name] = triple_to_constraint_set(exec_triple) + target_compatible_with_by_toolchain[toolchain.name] = toolchain.target_constraints + toolchain_types[toolchain.name] = "@rules_rust//rust:toolchain" + toolchain_target_settings[toolchain.name] = ["@rules_rust//rust/toolchain/channel:{}".format(toolchain.channel.name)] + + for exec_triple, name in rustfmt_toolchain_triples.items(): rustfmt_repo_name = "rustfmt_{}__{}".format(rustfmt_version.replace("/", "-"), exec_triple) if rustfmt_repo_name in aliases: rustfmt_repo_name = aliases.pop(rustfmt_repo_name) @@ -281,22 +304,6 @@ def rust_register_toolchains( rustfmt_repo_name, )) - for toolchain in _get_toolchain_repositories( - name = name, - exec_triple = exec_triple, - extra_target_triples = extra_target_triples, - versions = versions, - fallback_target_compatible_with = None, - aliases = aliases, - compact_windows_names = compact_windows_names, - ): - toolchain_names.append(toolchain.name) - toolchain_labels[toolchain.name] = "@{}//:{}".format(toolchain.name + "_tools", "rust_toolchain") - exec_compatible_with_by_toolchain[toolchain.name] = triple_to_constraint_set(exec_triple) - target_compatible_with_by_toolchain[toolchain.name] = toolchain.target_constraints - toolchain_types[toolchain.name] = "@rules_rust//rust:toolchain" - toolchain_target_settings[toolchain.name] = ["@rules_rust//rust/toolchain/channel:{}".format(toolchain.channel.name)] - toolchain_names.append(rustfmt_repo_name) toolchain_labels[rustfmt_repo_name] = "@{}_tools//:rustfmt_toolchain".format(rustfmt_repo_name) exec_compatible_with_by_toolchain[rustfmt_repo_name] = triple_to_constraint_set(exec_triple) @@ -307,6 +314,15 @@ def rust_register_toolchains( fail("No repositories were created matching the requested names to alias:\n{}".format("\n".join(sorted(aliases)))) if hub_name: + if extra_toolchain_infos: + for name, info in extra_toolchain_infos.items(): + toolchain_names.append(name) + toolchain_labels[name] = info["tools_toolchain_label"] + exec_compatible_with_by_toolchain[name] = info["exec_compatible_with"] + target_compatible_with_by_toolchain[name] = info["target_compatible_with"] + toolchain_target_settings[name] = info["target_settings"] + toolchain_types[name] = info["toolchain_type"] + toolchain_repository_hub( name = hub_name, toolchain_names = toolchain_names, @@ -628,7 +644,7 @@ def rust_toolchain_repository( auth_patterns (list, optional): A list of patterns to match against urls for which the auth object should be used. Returns: - str: The name of the registerable toolchain created by this rule. + dict[str, str]: Information about the registerable toolchain created by this rule. """ if exec_compatible_with == None: exec_compatible_with = triple_to_constraint_set(exec_triple) @@ -660,18 +676,28 @@ def rust_toolchain_repository( channel_target_settings = ["@rules_rust//rust/toolchain/channel:{}".format(channel)] if channel else [] + tools_toolchain_label = "@{}//:rust_toolchain".format(tools_repo_name) + + toolchain_type = "@rules_rust//rust:toolchain" + toolchain_repository_proxy( name = name, - toolchain = "@{}//:rust_toolchain".format(tools_repo_name), + toolchain = tools_toolchain_label, target_settings = channel_target_settings + target_settings, - toolchain_type = "@rules_rust//rust:toolchain", + toolchain_type = toolchain_type, exec_compatible_with = exec_compatible_with, target_compatible_with = target_compatible_with, ) - return "@{name}//:toolchain".format( - name = name, - ) + return { + "exec_compatible_with": exec_compatible_with, + "name": name, + "target_compatible_with": target_compatible_with, + "target_settings": target_settings, + "toolchain_label": "@{name}//:toolchain".format(name = name), + "toolchain_type": toolchain_type, + "tools_toolchain_label": tools_toolchain_label, + } _RUST_ANALYZER_TOOLCHAIN_TOOLS_REPOSITORY_ATTRS = { "auth": attr.string_dict( @@ -1131,9 +1157,13 @@ def rust_repository_set( aliases (dict): Replacement names to use for toolchains created by this macro. compact_windows_names (bool): Whether or not to produce compact repository names for windows toolchains. This is to avoid MAX_PATH issues. + + Returns: + dict[str, dict]: A dict of informations about all generated toolchains. """ - all_toolchain_names = [] + all_toolchain_details = {} + toolchain_labels = [] for toolchain in _get_toolchain_repositories( name = name, exec_triple = exec_triple, @@ -1153,7 +1183,7 @@ def rust_repository_set( else: fail("extra_rustc_flags should be a list or a dict") - all_toolchain_names.append(rust_toolchain_repository( + toolchain_info = rust_toolchain_repository( name = toolchain.name, allocator_library = allocator_library, global_allocator_library = global_allocator_library, @@ -1175,16 +1205,20 @@ def rust_repository_set( version = toolchain.channel.version, exec_compatible_with = exec_compatible_with, target_compatible_with = toolchain.target_constraints, - )) + ) + toolchain_labels.append(toolchain_info["toolchain_label"]) + all_toolchain_details[toolchain.name] = toolchain_info # This repository exists to allow `rust_repository_set` to work with the `maybe` wrapper. rust_toolchain_set_repository( name = name, - toolchains = all_toolchain_names, + toolchains = toolchain_labels, ) # Register toolchains if register_toolchain: - native.register_toolchains(*all_toolchain_names) + native.register_toolchains(*toolchain_labels) native.register_toolchains(str(Label("//rust/private/dummy_cc_toolchain:dummy_cc_wasm32_toolchain"))) native.register_toolchains(str(Label("//rust/private/dummy_cc_toolchain:dummy_cc_wasm64_toolchain"))) + + return all_toolchain_details