diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index b98647ea58..4e97538c11 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -534,6 +534,18 @@ tasks: - "//..." test_targets: - "//..." + cc_common_link_and_mangling_ubuntu2004: + name: Build via cc_common.link with rustc mangling alloc symbols + platform: ubuntu2004 + working_directory: test/integration/cc_common_link + build_targets: + - "//..." + test_targets: + - "//..." + build_flags: + - "--config=mangled_alloc_symbols" + test_flags: + - "--config=mangled_alloc_symbols" cc_common_link_with_global_alloc_ubuntu2004: name: Build via cc_common.link using a global allocator platform: ubuntu2004 @@ -550,6 +562,18 @@ tasks: - "//..." test_targets: - "//..." + cc_common_link_with_global_alloc_and_mangling_ubuntu2004: + name: Build via cc_common.link using a global allocator with rustc mangling alloc symbols + platform: ubuntu2004 + working_directory: test/integration/cc_common_link_with_global_alloc + build_targets: + - "//..." + test_targets: + - "//..." + build_flags: + - "--config=mangled_alloc_symbols" + test_flags: + - "--config=mangled_alloc_symbols" cc_common_link_no_std_ubuntu2004: name: Build with no_std + alloc using cc_common.link infrastructure for linking platform: ubuntu2004 @@ -562,6 +586,18 @@ tasks: - "--config=no_std_alloc_using_cc_common_link" test_flags: - "--config=no_std_alloc_using_cc_common_link" + cc_common_link_no_std_and_mangling_ubuntu2004: + name: Build with no_std + alloc using cc_common.link infrastructure for linking with rust toolchain mangling alloc symbols + platform: ubuntu2004 + working_directory: test/integration/no_std + build_targets: + - "//..." + test_targets: + - "//..." + build_flags: + - "--config=no_std_alloc_using_cc_common_link_and_mangled_alloc_symbols" + test_flags: + - "--config=no_std_alloc_using_cc_common_link_and_mangled_alloc_symbols" no_std_ubuntu2004: name: Build with no_std + alloc platform: ubuntu2004 diff --git a/ffi/rs/BUILD.bazel b/ffi/rs/BUILD.bazel new file mode 100644 index 0000000000..1fb2abebec --- /dev/null +++ b/ffi/rs/BUILD.bazel @@ -0,0 +1,40 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +# buildifier: disable=bzl-visibility +load("@rules_rust//rust/private:rust.bzl", "rust_allocator_libraries") + +rust_allocator_libraries( + name = "allocator_libraries_with_mangling_support", + allocator_library = "@rules_rust//ffi/rs/allocator_library", + global_allocator_library = "@rules_rust//ffi/rs/global_allocator_library", + visibility = ["//visibility:public"], +) + +rust_allocator_libraries( + name = "empty_allocator_libraries", + visibility = ["//visibility:public"], +) + +alias( + name = "default_allocator_libraries", + actual = select({ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_on": ":allocator_libraries_with_mangling_support", + "//conditions:default": ":empty_allocator_libraries", + }), + visibility = ["//visibility:public"], +) + +cc_library( + name = "empty", + visibility = ["//visibility:public"], +) + +# Allocator libraries used while bootstrapping the process wrapper. +rust_allocator_libraries( + name = "allocator_libraries_with_mangling_support_without_process_wrapper", + allocator_library = "@rules_rust//ffi/rs/allocator_library:allocator_library_without_process_wrapper", + # no need for a global allocator library, since the process wrapper + # is always bootstrapped in exec mode, which always uses the default + # allocator. + visibility = ["@rules_rust//util/process_wrapper:__subpackages__"], +) diff --git a/ffi/rs/allocator_library/BUILD.bazel b/ffi/rs/allocator_library/BUILD.bazel new file mode 100644 index 0000000000..76a776c13e --- /dev/null +++ b/ffi/rs/allocator_library/BUILD.bazel @@ -0,0 +1,35 @@ +load("@rules_rust//rust:defs.bzl", "rust_library") + +# buildifier: disable=bzl-visibility +load( + "@rules_rust//rust/private:rust.bzl", + "rust_library_without_process_wrapper", +) + +package( + default_visibility = ["@rules_rust//ffi/rs:__subpackages__"], +) + +srcs = select({ + # Windows doesn't support weak symbol linkage. + # If someone can make this work on Windows, please do! + # For now we will silently not supply any symbols, because it would be very messy to conditionally define the default allocator library on toolchains depending on the platform. + "@platforms//os:windows": ["empty.rs"], + "//conditions:default": ["allocator_library.rs"], +}) + +rust_library( + name = "allocator_library", + srcs = srcs, + allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", + edition = "2024", + tags = ["manual"], +) + +rust_library_without_process_wrapper( + name = "allocator_library_without_process_wrapper", + srcs = srcs, + allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", + edition = "2024", + tags = ["manual"], +) diff --git a/ffi/rs/allocator_library/allocator_library.rs b/ffi/rs/allocator_library/allocator_library.rs new file mode 100644 index 0000000000..fb498d81d7 --- /dev/null +++ b/ffi/rs/allocator_library/allocator_library.rs @@ -0,0 +1,86 @@ +// Workaround for Rust issue https://github.com/rust-lang/rust/issues/73632 +// We provide the allocator functions that rustc leaves in rlibs. These are +// normally provided by rustc during the linking phase (since the allocator in +// use can vary), but if rustc doesn't do the final link we have to provide +// these manually. Hopefully we can make progress on the above bug and +// eventually not need this kludge. +// +// Recently rustc started mangling these symbols, so we rewrote them in +// rust. +// https://github.com/rust-lang/rust/pull/127173 +// +// This code uses unstable internal rustc features that are only available when +// using a nightly toolchain. Also, it is only compatible with versions +// of rustc that include the symbol mangling, such as nightly/2025-04-08 or +// later. +// +// This has been translated from our c++ version +// rules_rust/ffi/cc/allocator_library/allocator_library.cc. +#![no_std] +#![allow(warnings)] +#![allow(internal_features)] +#![feature(rustc_attrs)] +#![feature(linkage)] + +unsafe extern "C" { + #[rustc_std_internal_symbol] + fn __rdl_alloc(size: usize, align: usize) -> *mut u8; + + #[rustc_std_internal_symbol] + fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize); + + #[rustc_std_internal_symbol] + fn __rdl_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; + + #[rustc_std_internal_symbol] + fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8; +} + +#[linkage = "weak"] +#[rustc_std_internal_symbol] +fn __rust_alloc(size: usize, align: usize) -> *mut u8 { + unsafe { + return __rdl_alloc(size, align); + } +} + +#[linkage = "weak"] +#[rustc_std_internal_symbol] +fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize) { + unsafe { + return __rdl_dealloc(ptr, size, align); + } +} + +#[linkage = "weak"] +#[rustc_std_internal_symbol] +fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8 { + unsafe { + return __rdl_realloc(ptr, old_size, align, new_size); + } +} + +#[linkage = "weak"] +#[rustc_std_internal_symbol] +fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 { + unsafe { + return __rdl_alloc_zeroed(size, align); + } +} + +#[linkage = "weak"] +#[rustc_std_internal_symbol] +fn __rust_alloc_error_handler(size: usize, align: usize) { + panic!(); +} + +// New feature as of https://github.com/rust-lang/rust/pull/88098. +// This symbol is normally emitted by rustc. 0 means OOMs should abort, 1 means OOMs should panic. +#[linkage = "weak"] +#[rustc_std_internal_symbol] +static mut __rust_alloc_error_handler_should_panic: u8 = 1; + +// See https://github.com/rust-lang/rust/issues/73632#issuecomment-1563462239 +#[linkage = "weak"] +#[rustc_std_internal_symbol] +static mut __rust_no_alloc_shim_is_unstable: u8 = 0; diff --git a/ffi/rs/allocator_library/empty.rs b/ffi/rs/allocator_library/empty.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ffi/rs/global_allocator_library/BUILD.bazel b/ffi/rs/global_allocator_library/BUILD.bazel new file mode 100644 index 0000000000..743c98d334 --- /dev/null +++ b/ffi/rs/global_allocator_library/BUILD.bazel @@ -0,0 +1,21 @@ +load("@rules_rust//rust:defs.bzl", "rust_library") + +package( + default_visibility = ["@rules_rust//ffi/rs:__subpackages__"], +) + +srcs = select({ + # Windows doesn't support weak symbol linkage. + # If someone can make this work on Windows, please do! + # For now we will silently not supply any symbols, because it would be very messy to conditionally define the global allocator library on toolchains depending on the platform. + "@platforms//os:windows": ["empty.rs"], + "//conditions:default": ["global_allocator_library.rs"], +}) + +rust_library( + name = "global_allocator_library", + srcs = srcs, + allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", + edition = "2024", + tags = ["manual"], +) diff --git a/ffi/rs/global_allocator_library/empty.rs b/ffi/rs/global_allocator_library/empty.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ffi/rs/global_allocator_library/global_allocator_library.rs b/ffi/rs/global_allocator_library/global_allocator_library.rs new file mode 100644 index 0000000000..44dbe88ea3 --- /dev/null +++ b/ffi/rs/global_allocator_library/global_allocator_library.rs @@ -0,0 +1,48 @@ +// Workaround for Rust issue https://github.com/rust-lang/rust/issues/73632 +// We provide the allocator functions that rustc leaves in rlibs. These are +// normally provided by rustc during the linking phase (since the allocator in +// use can vary), but if rustc doesn't do the final link we have to provide +// these manually. Hopefully we can make progress on the above bug and +// eventually not need this kludge. +// +// Recently rustc started mangling these symbols, so we rewrote them in +// rust. +// https://github.com/rust-lang/rust/pull/127173 +// +// This code uses unstable internal rustc features that are only available when +// using a nightly toolchain. Also, it is only compatible with versions +// of rustc that include the symbol mangling, such as nightly/2025-04-08 or +// later. +// +// This has been translated from our c++ version +// rules_rust/ffi/cc/global_allocator_library/global_allocator_library.cc. +#![no_std] +#![allow(warnings)] +#![allow(internal_features)] +#![feature(rustc_attrs)] +#![feature(linkage)] + +unsafe extern "C" { + #[rustc_std_internal_symbol] + fn __rg_oom(size: usize, align: usize) -> *mut u8; +} + +#[linkage = "weak"] +#[rustc_std_internal_symbol] +fn __rust_alloc_error_handler(size: usize, align: usize) { + unsafe { + __rg_oom(size, align); + } +} + + +// New feature as of https://github.com/rust-lang/rust/pull/88098. +// This symbol is normally emitted by rustc. 0 means OOMs should abort, 1 means OOMs should panic. +#[linkage = "weak"] +#[rustc_std_internal_symbol] +static mut __rust_alloc_error_handler_should_panic: u8 = 1; + +// See https://github.com/rust-lang/rust/issues/73632#issuecomment-1563462239 +#[linkage = "weak"] +#[rustc_std_internal_symbol] +static mut __rust_no_alloc_shim_is_unstable: u8 = 0; diff --git a/rust/extensions.bzl b/rust/extensions.bzl index b89f79898c..99868b0dfe 100644 --- a/rust/extensions.bzl +++ b/rust/extensions.bzl @@ -64,6 +64,7 @@ def _rust_impl(module_ctx): "name": repository_set.name, "rustfmt_version": repository_set.rustfmt_version, "sha256s": repository_set.sha256s, + "target_settings": [str(v) for v in repository_set.target_settings], "urls": repository_set.urls, "versions": repository_set.versions, } @@ -119,6 +120,7 @@ def _rust_impl(module_ctx): register_toolchains = False, aliases = toolchain.aliases, toolchain_triples = toolchain_triples, + target_settings = [str(v) for v in toolchain.target_settings], extra_toolchain_infos = extra_toolchain_infos, ) metadata_kwargs = {} @@ -170,6 +172,9 @@ _RUST_REPOSITORY_SET_TAG_ATTRS = { "target_compatible_with": attr.label_list( doc = "List of platform constraints this toolchain produces, for the particular target_triple this call is for.", ), + "target_settings": attr.label_list( + doc = "A list of `config_settings` that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution.", + ), "target_triple": attr.string( doc = "target_triple to configure.", ), @@ -214,6 +219,9 @@ _RUST_TOOLCHAIN_TAG = tag_class( "rust_analyzer_version": attr.string( doc = "The version of Rustc to pair with rust-analyzer.", ), + "target_settings": attr.label_list( + doc = "A list of `config_settings` that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution.", + ), "versions": attr.string_list( doc = ( "A list of toolchain versions to download. This parameter only accepts one version " + diff --git a/rust/private/providers.bzl b/rust/private/providers.bzl index 746370bc70..5c47bf14cb 100644 --- a/rust/private/providers.bzl +++ b/rust/private/providers.bzl @@ -188,3 +188,21 @@ LintsInfo = provider( "rustdoc_lint_flags": "List[String]: rustc flags to specify when building rust_doc targets.", }, ) + +AllocatorLibrariesInfo = provider( + doc = "AllocatorLibrariesInfo provides allocator libraries for linking rust code with a non-rust linker.", + fields = { + "allocator_library": "Optional[CcInfo]: used when the default rust allocator is used", + "global_allocator_library": "Optional[CcInfo]: used when a global rust allocator is used", + "libstd_and_allocator_ccinfo": "Optional[CcInfo]: used when the default rust allocator is used", + "libstd_and_global_allocator_ccinfo": "Optional[CcInfo]: used when a global rust allocator is used", + "nostd_and_global_allocator_ccinfo": "Optional[CcInfo]: used when nostd with a global rust allocator is used", + }, +) + +AllocatorLibrariesImplInfo = provider( + doc = "AllocatorLibrariesImplInfo provides the rust-generated linker input for linking rust code with a non-rust linker.", + fields = { + "static_archive": "Optional[File]: the allocator library archive (typically .a file).", + }, +) diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 74d458eef9..dba253b1c0 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -17,7 +17,13 @@ load("@bazel_skylib//lib:paths.bzl", "paths") load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//rust/private:common.bzl", "COMMON_PROVIDERS", "rust_common") -load("//rust/private:providers.bzl", "BuildInfo", "LintsInfo") +load( + "//rust/private:providers.bzl", + "AllocatorLibrariesImplInfo", + "AllocatorLibrariesInfo", + "BuildInfo", + "LintsInfo", +) load("//rust/private:rustc.bzl", "rustc_compile_action") load( "//rust/private:utils.bzl", @@ -564,6 +570,19 @@ RUSTC_ATTRS = { ), } +# Attributes for rust-based allocator library support. +# Can't add it directly to RUSTC_ATTRS above, as those are used as +# aspect parameters and only support simple types ('bool', 'int' or 'string'). +_rustc_allocator_libraries_attrs = { + # This is really internal. Not prefixed with `_` since we need to adapt this + # in bootstrapping situations, e.g., when building the process wrapper + # or allocator libraries themselves. + "allocator_libraries": attr.label( + default = "//ffi/rs:default_allocator_libraries", + providers = [AllocatorLibrariesInfo], + ), +} + _common_attrs = { "aliases": attr.label_keyed_string_dict( doc = dedent("""\ @@ -723,7 +742,7 @@ _common_attrs = { doc = "A setting used to determine whether or not the `--stamp` flag is enabled", default = Label("//rust/private:stamp"), ), -} | RUSTC_ATTRS +} | RUSTC_ATTRS | _rustc_allocator_libraries_attrs _coverage_attrs = { "_collect_cc_coverage": attr.label( @@ -1573,6 +1592,47 @@ rust_library_group = rule( """), ) +def _rust_allocator_libraries_impl(ctx): + toolchain = find_toolchain(ctx) + allocator_library = ctx.attr.allocator_library[AllocatorLibrariesImplInfo] if ctx.attr.allocator_library else None + global_allocator_library = ctx.attr.global_allocator_library[AllocatorLibrariesImplInfo] if ctx.attr.global_allocator_library else None + + make_ccinfo = lambda info, std: toolchain.make_libstd_and_allocator_ccinfo( + ctx.label, + ctx.actions, + struct(allocator_libraries_impl_info = info), + std, + ) + + providers = [AllocatorLibrariesInfo( + allocator_library = allocator_library, + global_allocator_library = global_allocator_library, + libstd_and_allocator_ccinfo = make_ccinfo(allocator_library, "std"), + libstd_and_global_allocator_ccinfo = make_ccinfo(global_allocator_library, "std"), + nostd_and_global_allocator_ccinfo = make_ccinfo(global_allocator_library, "no_std_with_alloc"), + )] + + return providers + +rust_allocator_libraries = rule( + implementation = _rust_allocator_libraries_impl, + provides = [AllocatorLibrariesInfo], + attrs = { + "allocator_library": attr.label( + doc = "An optional library to provide when a default rust allocator is used.", + providers = [AllocatorLibrariesImplInfo], + ), + "global_allocator_library": attr.label( + doc = "An optional library to provide when a default rust allocator is used.", + providers = [AllocatorLibrariesImplInfo], + ), + }, + toolchains = [ + str(Label("//rust:toolchain_type")), + "@bazel_tools//tools/cpp:toolchain_type", + ], +) + def _replace_illlegal_chars(name): """Replaces illegal characters in a name with underscores. diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index d78c28902c..8062de4c0f 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -27,7 +27,7 @@ load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load(":common.bzl", "rust_common") load(":compat.bzl", "abs") load(":lto.bzl", "construct_lto_arguments") -load(":providers.bzl", "LintsInfo", "RustcOutputDiagnosticsInfo", _BuildInfo = "BuildInfo") +load(":providers.bzl", "AllocatorLibrariesImplInfo", "AllocatorLibrariesInfo", "LintsInfo", "RustcOutputDiagnosticsInfo", _BuildInfo = "BuildInfo") load(":rustc_resource_set.bzl", "get_rustc_resource_set", "is_codegen_units_enabled") load(":stamp.bzl", "is_stamping_enabled") load( @@ -1604,16 +1604,50 @@ def _is_no_std(ctx, toolchain, crate_info): return False return True +def _should_use_rustc_allocator_libraries(toolchain): + use_or_default = toolchain._experimental_use_allocator_libraries_with_mangled_symbols + if use_or_default not in [-1, 0, 1]: + fail("unexpected value of experimental_use_allocator_libraries_with_mangled_symbols (should be one of [-1, 0, 1]): " + use_or_default) + if use_or_default == -1: + return toolchain._experimental_use_allocator_libraries_with_mangled_symbols_setting + return bool(use_or_default) + def _get_std_and_alloc_info(ctx, toolchain, crate_info): + # Handles standard libraries and allocator shims. + # + # The standard libraries vary between "std" and "nostd" flavors. + # + # The allocator libraries vary along two dimensions: + # * the type of rust allocator used (default or global) + # * the mechanism providing the libraries (via the rust rules + # allocator_libraries attribute, or via the rust toolchain allocator + # attributes). + # + # When provided, the allocator_libraries attribute takes precedence over the + # toolchain allocator attributes. + libs = None + attr_allocator_library = None + attr_global_allocator_library = None + if _should_use_rustc_allocator_libraries(toolchain) and hasattr(ctx.attr, "allocator_libraries"): + libs = ctx.attr.allocator_libraries[AllocatorLibrariesInfo] + attr_allocator_library = libs.allocator_library + attr_global_allocator_library = libs.global_allocator_library if is_exec_configuration(ctx): + if attr_allocator_library: + return libs.libstd_and_allocator_ccinfo return toolchain.libstd_and_allocator_ccinfo if toolchain._experimental_use_global_allocator: if _is_no_std(ctx, toolchain, crate_info): - return toolchain.nostd_and_global_allocator_cc_info + if attr_global_allocator_library: + return libs.nostd_and_global_allocator_ccinfo + return toolchain.nostd_and_global_allocator_ccinfo else: + if attr_global_allocator_library: + return libs.libstd_and_global_allocator_ccinfo return toolchain.libstd_and_global_allocator_ccinfo - else: - return toolchain.libstd_and_allocator_ccinfo + if attr_allocator_library: + return libs.libstd_and_allocator_ccinfo + return toolchain.libstd_and_allocator_ccinfo def _is_dylib(dep): return not bool(dep.static_library or dep.pic_static_library) @@ -1680,7 +1714,8 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co interface_library (File): Optional interface library for cdylib crates on Windows. Returns: - list: A list containing the CcInfo provider + list: A list containing the CcInfo provider and optionally AllocatorLibrariesImplInfo provider used when this crate is used as the rust allocator library implementation. + """ # A test will not need to produce CcInfo as nothing can depend on test targets @@ -1696,6 +1731,8 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co if getattr(attr, "out_binary", False): return [] + dot_a = None + if crate_info.type == "staticlib": library_to_link = cc_common.create_library_to_link( actions = ctx.actions, @@ -1769,7 +1806,10 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co # TODO: if we already have an rlib in our deps, we could skip this cc_infos.append(libstd_and_allocator_cc_info) - return [cc_common.merge_cc_infos(cc_infos = cc_infos)] + providers = [cc_common.merge_cc_infos(cc_infos = cc_infos)] + if dot_a: + providers.append(AllocatorLibrariesImplInfo(static_archive = dot_a)) + return providers def add_edition_flags(args, crate): """Adds the Rust edition flag to an arguments object reference diff --git a/rust/repositories.bzl b/rust/repositories.bzl index a5df38421e..7dc9d912d8 100644 --- a/rust/repositories.bzl +++ b/rust/repositories.bzl @@ -159,6 +159,7 @@ def rust_register_toolchains( compact_windows_names = _COMPACT_WINDOWS_NAMES, toolchain_triples = DEFAULT_TOOLCHAIN_TRIPLES, rustfmt_toolchain_triples = DEFAULT_TOOLCHAIN_TRIPLES, + target_settings = [], extra_toolchain_infos = None): """Emits a default set of toolchains for Linux, MacOS, and Freebsd @@ -199,6 +200,7 @@ def rust_register_toolchains( 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. + target_settings (list of labels as strings, optional): A list of `config_settings` that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution. 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: @@ -287,7 +289,7 @@ def rust_register_toolchains( 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_target_settings[toolchain.name] = ["@rules_rust//rust/toolchain/channel:{}".format(toolchain.channel.name)] + target_settings for exec_triple, name in rustfmt_toolchain_triples.items(): rustfmt_repo_name = "rustfmt_{}__{}".format(rustfmt_version.replace("/", "-"), exec_triple) @@ -633,7 +635,7 @@ def rust_toolchain_repository( channel (str, optional): The channel of the Rust toolchain. exec_compatible_with (list, optional): A list of constraints for the execution platform for this toolchain. target_compatible_with (list, optional): A list of constraints for the target platform for this toolchain. - target_settings (list, optional): A list of config_settings that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution. + target_settings (list of labels as strings, optional): A list of config_settings that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution. allocator_library (str, optional): Target that provides allocator functions when rust_library targets are embedded in a cc_binary. global_allocator_library (str, optional): Target that provides allocator functions when a global allocator is used with cc_common.link. rustfmt_version (str, optional): The version of rustfmt to be associated with the @@ -1136,7 +1138,7 @@ def rust_repository_set( versions (list, optional): A list of toolchain versions to download. This paramter only accepts one versions per channel. E.g. `["1.65.0", "nightly/2022-11-02", "beta/2020-12-30"]`. exec_triple (str): The Rust-style target that this compiler runs on - target_settings (list, optional): A list of config_settings that must be satisfied by the target configuration in order for this set of toolchains to be selected during toolchain resolution. + target_settings (list of labels as strings, optional): A list of config_settings that must be satisfied by the target configuration in order for this set of toolchains to be selected during toolchain resolution. allocator_library (str, optional): Target that provides allocator functions when rust_library targets are embedded in a cc_binary. global_allocator_library (str, optional): Target that provides allocator functions a global allocator is used with cc_common.link. diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index 8fb46461d8..d24237a078 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -9,6 +9,7 @@ load( "error_format", "experimental_link_std_dylib", "experimental_per_crate_rustc_flag", + "experimental_use_allocator_libraries_with_mangled_symbols", "experimental_use_cc_common_link", "experimental_use_coverage_metadata_files", "experimental_use_global_allocator", @@ -71,6 +72,10 @@ experimental_use_coverage_metadata_files() experimental_use_global_allocator() +experimental_use_allocator_libraries_with_mangled_symbols( + name = "experimental_use_allocator_libraries_with_mangled_symbols", +) + experimental_use_sh_toolchain_for_bootstrap_process_wrapper() extra_exec_rustc_flag() diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index 1444600d2d..e19320319e 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -125,6 +125,68 @@ def experimental_use_global_allocator(): build_setting_default = False, ) +def experimental_use_allocator_libraries_with_mangled_symbols(name): + """A flag used to select allocator libraries implemented in rust that are compatible with the rustc allocator symbol mangling. + + The symbol mangling mechanism relies on unstable language features and requires a nightly rustc from 2025-04-05 or later. + + Rustc generates references to internal allocator symbols when building rust + libraries. At link time, rustc generates the definitions of these symbols. + When rustc is not used as the final linker, we need to generate the + definitions ourselves. This happens for example when a rust_library is + used as a dependency of a rust_binary, or when the + experimental_use_cc_common_link setting is used. + + + For older versions of rustc, the allocator symbol definitions can be provided + via the `rust_toolchain`'s `allocator_library` or `global_allocator_library` + attributes, with sample targets like `@rules_rust//ffi/cc/allocator_library` + and `@rules_rust//ffi/cc/global_allocator_library`. + + Recent versions of rustc started mangling these allocator symbols (https://github.com/rust-lang/rust/pull/127173). + The mangling uses a scheme that is specific to the exact version of the compiler. + This makes the cc allocator library definitions ineffective. To work around + this, we provide rust versions of the symbol definitions annotated with + an unstable language attribute that instructs rustc to mangle them consistently. + Because of that, this is only compatible with nightly versions of the compiler. + + Since the new symbol definitions are written in rust, we cannot just attach + them as attributes on the `rust_toolchain` as the old cc versions, as that + would create a build graph cycle (we need a `rust_toolchain` to build a + `rust_library`, so the allocator library cannot be a rust_library directly). + + The bootstrapping cycle can be avoided by defining a separate internal + "initial" rust toolchain specifically for building the rust allocator libraries, + and use a transition to attach the generated libraries to the "main" rust + toolchain. But that duplicates the whole sub-graph of the build around the + rust toolchains, repository and supporting tools used for them. + + Instead, we define a new custom `rust_allocator_library` rule, which exposes + the result of building the rust allocator libraries via a provider, which + can be consumed by the rust build actions. We attach an instance of this + as a common attribute to the rust rule set. + + TODO: how this interacts with stdlibs + """ + bool_flag( + name = name, + build_setting_default = False, + ) + + native.config_setting( + name = "%s_on" % name, + flag_values = { + ":experimental_use_allocator_libraries_with_mangled_symbols": "true", + }, + ) + + native.config_setting( + name = "%s_off" % name, + flag_values = { + ":experimental_use_allocator_libraries_with_mangled_symbols": "false", + }, + ) + def experimental_use_coverage_metadata_files(): """A flag to have coverage tooling added as `coverage_common.instrumented_files_info.metadata_files` instead of \ reporting tools like `llvm-cov` and `llvm-profdata` as runfiles to each test. diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 1db18bcd3c..dcb6963bff 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -124,12 +124,12 @@ rust_stdlib_filegroup = rule( }, ) -def _ltl(library, ctx, cc_toolchain, feature_configuration): +def _ltl(library, actions, cc_toolchain, feature_configuration): """A helper to generate `LibraryToLink` objects Args: library (File): A rust library file to link. - ctx (ctx): The rule's context object. + actions: The rule's ctx.actions object. cc_toolchain (CcToolchainInfo): A cc toolchain provider to be used. feature_configuration (feature_configuration): feature_configuration to be queried. @@ -137,20 +137,35 @@ def _ltl(library, ctx, cc_toolchain, feature_configuration): LibraryToLink: A provider containing information about libraries to link. """ return cc_common.create_library_to_link( - actions = ctx.actions, + actions = actions, feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, static_library = library, pic_static_library = library, ) -def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "std"): +def _make_libstd_and_allocator_ccinfo( + cc_toolchain, + feature_configuration, + label, + actions, + experimental_link_std_dylib, + rust_std, + allocator_library, + std = "std"): """Make the CcInfo (if possible) for libstd and allocator libraries. Args: - ctx (ctx): The rule's context object. + cc_toolchain (CcToolchainInfo): A cc toolchain provider to be used. + feature_configuration (feature_configuration): feature_configuration to be queried. + label (Label): The rule's label. + actions: The rule's ctx.actions object. + experimental_link_std_dylib (boolean): The value of the standard library's `_experimental_link_std_dylib(ctx)`. rust_std: The Rust standard library. - allocator_library: The target to use for providing allocator functions. + allocator_library (struct): The target to use for providing allocator functions. + This should be a struct with either: + * a cc_info field of type CcInfo + * an allocator_libraries_impl_info field, which should be None or of type AllocatorLibrariesImplInfo. std: Standard library flavor. Currently only "std" and "no_std_with_alloc" are supported, accompanied with the default panic behavior. @@ -158,8 +173,11 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s Returns: A CcInfo object for the required libraries, or None if no such libraries are available. """ - cc_toolchain, feature_configuration = find_cc_toolchain(ctx) cc_infos = [] + if not type(allocator_library) == "struct": + fail("Unexpected type of allocator_library, it must be a struct.") + if not any([hasattr(allocator_library, field) for field in ["cc_info", "allocator_libraries_impl_info"]]): + fail("Unexpected contents of allocator_library, it must provide either a cc_info or an allocator_libraries_impl_info.") if not rust_common.stdlib_info in rust_std: fail(dedent("""\ @@ -167,7 +185,7 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s The `rust_lib` ({}) must be a target providing `rust_common.stdlib_info` (typically `rust_stdlib_filegroup` rule from @rules_rust//rust:defs.bzl). See https://github.com/bazelbuild/rules_rust/pull/802 for more information. - """).format(ctx.label, rust_std)) + """).format(label, rust_std)) rust_stdlib_info = rust_std[rust_common.stdlib_info] if rust_stdlib_info.self_contained_files: @@ -176,8 +194,8 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s ) linking_context, _linking_outputs = cc_common.create_linking_context_from_compilation_outputs( - name = ctx.label.name, - actions = ctx.actions, + name = label.name, + actions = actions, feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, compilation_outputs = compilation_outputs, @@ -188,16 +206,26 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s )) if rust_stdlib_info.std_rlibs: + allocator_library_inputs = [] + + if hasattr(allocator_library, "allocator_libraries_impl_info") and allocator_library.allocator_libraries_impl_info: + static_archive = allocator_library.allocator_libraries_impl_info.static_archive + allocator_library_inputs = [depset( + [_ltl(static_archive, actions, cc_toolchain, feature_configuration)], + )] + alloc_inputs = depset( - [_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.alloc_files], + [_ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.alloc_files], + transitive = allocator_library_inputs, + order = "topological", ) between_alloc_and_core_inputs = depset( - [_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.between_alloc_and_core_files], + [_ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.between_alloc_and_core_files], transitive = [alloc_inputs], order = "topological", ) core_inputs = depset( - [_ltl(f, ctx, cc_toolchain, feature_configuration) for f in rust_stdlib_info.core_files], + [_ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.core_files], transitive = [between_alloc_and_core_inputs], order = "topological", ) @@ -220,7 +248,7 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s ] core_alloc_and_panic_inputs = depset( [ - _ltl(f, ctx, cc_toolchain, feature_configuration) + _ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.panic_files if "unwind" not in f.basename ], @@ -230,7 +258,7 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s else: core_alloc_and_panic_inputs = depset( [ - _ltl(f, ctx, cc_toolchain, feature_configuration) + _ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.panic_files if "unwind" not in f.basename ], @@ -239,7 +267,7 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s ) memchr_inputs = depset( [ - _ltl(f, ctx, cc_toolchain, feature_configuration) + _ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.memchr_files ], transitive = [core_inputs], @@ -247,18 +275,18 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s ) between_core_and_std_inputs = depset( [ - _ltl(f, ctx, cc_toolchain, feature_configuration) + _ltl(f, actions, cc_toolchain, feature_configuration) for f in filtered_between_core_and_std_files ], transitive = [memchr_inputs], order = "topological", ) - if _experimental_link_std_dylib(ctx): + if experimental_link_std_dylib: # std dylib has everything so that we do not need to include all std_files std_inputs = depset( [cc_common.create_library_to_link( - actions = ctx.actions, + actions = actions, feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, dynamic_library = rust_stdlib_info.std_dylib, @@ -267,7 +295,7 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s else: std_inputs = depset( [ - _ltl(f, ctx, cc_toolchain, feature_configuration) + _ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.std_files ], transitive = [between_core_and_std_inputs], @@ -276,7 +304,7 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s test_inputs = depset( [ - _ltl(f, ctx, cc_toolchain, feature_configuration) + _ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.test_files ], transitive = [std_inputs], @@ -297,8 +325,8 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s fail("Requested '{}' std mode is currently not supported.".format(std)) allocator_inputs = None - if allocator_library: - allocator_inputs = [allocator_library[CcInfo].linking_context.linker_inputs] + if hasattr(allocator_library, "cc_info"): + allocator_inputs = [allocator_library.cc_info.linking_context.linker_inputs] cc_infos.append(CcInfo( linking_context = cc_common.create_linking_context( @@ -657,6 +685,17 @@ def _rust_toolchain_impl(ctx): fail("Either `target_triple` or `target_json` must be provided. Please update {}".format( ctx.label, )) + cc_toolchain, feature_configuration = find_cc_toolchain(ctx) + experimental_link_std_dylib = _experimental_link_std_dylib(ctx) + make_ccinfo = lambda label, actions, allocator_library, std: ( + _make_libstd_and_allocator_ccinfo(cc_toolchain, feature_configuration, label, actions, experimental_link_std_dylib, rust_std, allocator_library, std) + ) + make_local_ccinfo = lambda allocator_library, std: make_ccinfo( + ctx.label, + ctx.actions, + struct(cc_info = allocator_library), + std, + ) toolchain = platform_common.ToolchainInfo( all_files = sysroot.all_files, @@ -669,9 +708,10 @@ def _rust_toolchain_impl(ctx): dylib_ext = ctx.attr.dylib_ext, env = ctx.attr.env, exec_triple = exec_triple, - libstd_and_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, ctx.attr.allocator_library, "std"), - libstd_and_global_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, ctx.attr.global_allocator_library, "std"), - nostd_and_global_allocator_cc_info = _make_libstd_and_allocator_ccinfo(ctx, rust_std, ctx.attr.global_allocator_library, "no_std_with_alloc"), + libstd_and_allocator_ccinfo = make_local_ccinfo(ctx.attr.allocator_library[CcInfo], "std"), + libstd_and_global_allocator_ccinfo = make_local_ccinfo(ctx.attr.global_allocator_library[CcInfo], "std"), + nostd_and_global_allocator_ccinfo = make_local_ccinfo(ctx.attr.global_allocator_library[CcInfo], "no_std_with_alloc"), + make_libstd_and_allocator_ccinfo = make_ccinfo, llvm_cov = ctx.file.llvm_cov, llvm_profdata = ctx.file.llvm_profdata, lto = lto, @@ -709,6 +749,8 @@ def _rust_toolchain_impl(ctx): _incompatible_do_not_include_data_in_compile_data = ctx.attr._incompatible_do_not_include_data_in_compile_data[IncompatibleFlagInfo].enabled, _no_std = no_std, _codegen_units = ctx.attr._codegen_units[BuildSettingInfo].value, + _experimental_use_allocator_libraries_with_mangled_symbols = ctx.attr.experimental_use_allocator_libraries_with_mangled_symbols, + _experimental_use_allocator_libraries_with_mangled_symbols_setting = ctx.attr._experimental_use_allocator_libraries_with_mangled_symbols_setting[BuildSettingInfo].value, ) return [ toolchain, @@ -779,6 +821,19 @@ rust_toolchain = rule( default = Label("@rules_rust//rust/settings:experimental_link_std_dylib"), doc = "Label to a boolean build setting that controls whether whether to link libstd dynamically.", ), + "experimental_use_allocator_libraries_with_mangled_symbols": attr.int( + doc = ( + "Whether to use rust-based allocator libraries with " + + "mangled symbols. Possible values: [-1, 0, 1]. " + + "-1 means to use the value of the build setting " + + "//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols. " + + "0 means do not use. In that case, rules_rust will try to use " + + "the c-based allocator libraries that don't support symbol mangling. " + + "1 means use the rust-based allocator libraries." + ), + values = [-1, 0, 1], + default = -1, + ), "experimental_use_cc_common_link": attr.label( default = Label("//rust/settings:experimental_use_cc_common_link"), doc = "Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries.", @@ -887,6 +942,14 @@ rust_toolchain = rule( "_codegen_units": attr.label( default = Label("//rust/settings:codegen_units"), ), + "_experimental_use_allocator_libraries_with_mangled_symbols_setting": attr.label( + default = Label("//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols"), + providers = [BuildSettingInfo], + doc = ( + "Label to a boolean build setting that informs the target build whether to use rust-based " + + "allocator libraries that mangle symbols." + ), + ), "_experimental_use_coverage_metadata_files": attr.label( default = Label("//rust/settings:experimental_use_coverage_metadata_files"), ), diff --git a/test/integration/cc_common_link/.bazelrc b/test/integration/cc_common_link/.bazelrc index 750da55999..5a87dbae73 100644 --- a/test/integration/cc_common_link/.bazelrc +++ b/test/integration/cc_common_link/.bazelrc @@ -3,6 +3,7 @@ ############################################################################### build --@rules_rust//rust/settings:experimental_use_cc_common_link=True +build:mangled_alloc_symbols --@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols=True ############################################################################### diff --git a/test/integration/cc_common_link/MODULE.bazel b/test/integration/cc_common_link/MODULE.bazel index 4a7e3a2594..249366e6ee 100644 --- a/test/integration/cc_common_link/MODULE.bazel +++ b/test/integration/cc_common_link/MODULE.bazel @@ -16,6 +16,30 @@ bazel_dep(name = "platforms", version = "0.0.11") rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") rust.toolchain( edition = "2018", + target_settings = [ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_off", + ], +) + +# Generate a toolchain to be used for rust-based allocator symbols. + +# A recent enough version of rustc that mangles the internal allocator symbols. +VERSION = "nightly/2025-04-08" + +rust.repository_set( + name = "rust_with_alloc_mangling_linux_x86_64", + allocator_library = "@rules_rust//ffi/rs:empty", + edition = "2021", + exec_triple = "x86_64-unknown-linux-gnu", + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_settings = [ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_on", + ], + target_triple = "x86_64-unknown-linux-gnu", + versions = [VERSION], ) use_repo(rust, "rust_toolchains") diff --git a/test/integration/cc_common_link_with_global_alloc/.bazelrc b/test/integration/cc_common_link_with_global_alloc/.bazelrc index 9b55c26368..9cb01c8f00 100644 --- a/test/integration/cc_common_link_with_global_alloc/.bazelrc +++ b/test/integration/cc_common_link_with_global_alloc/.bazelrc @@ -4,6 +4,7 @@ build --@rules_rust//rust/settings:experimental_use_cc_common_link=True build --@rules_rust//rust/settings:experimental_use_global_allocator=True +build:mangled_alloc_symbols --@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols=True ############################################################################### diff --git a/test/integration/cc_common_link_with_global_alloc/MODULE.bazel b/test/integration/cc_common_link_with_global_alloc/MODULE.bazel index 6d744a237d..4dfb4789e8 100644 --- a/test/integration/cc_common_link_with_global_alloc/MODULE.bazel +++ b/test/integration/cc_common_link_with_global_alloc/MODULE.bazel @@ -10,10 +10,34 @@ local_path_override( ) bazel_dep(name = "rules_cc", version = "0.1.1") +bazel_dep(name = "platforms", version = "0.0.11") rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") rust.toolchain( edition = "2018", + target_settings = [ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_off", + ], +) +# Generate a toolchain to be used for rust-based allocator symbols. + +# A recent enough version of rustc that mangles the internal allocator symbols. +VERSION = "nightly/2025-04-08" + +rust.repository_set( + name = "rust_with_alloc_mangling_linux_x86_64", + allocator_library = "@rules_rust//ffi/rs:empty", + edition = "2021", + exec_triple = "x86_64-unknown-linux-gnu", + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_settings = [ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_on", + ], + target_triple = "x86_64-unknown-linux-gnu", + versions = [VERSION], ) use_repo(rust, "rust_toolchains") diff --git a/test/integration/no_std/.bazelrc b/test/integration/no_std/.bazelrc index a01c55bdfb..cab64f52a3 100644 --- a/test/integration/no_std/.bazelrc +++ b/test/integration/no_std/.bazelrc @@ -11,6 +11,10 @@ build:no_std_alloc_using_cc_common_link --@rules_rust//rust/settings:experimenta build:no_std_alloc_using_cc_common_link --@rules_rust//rust/settings:experimental_use_global_allocator=True build:no_std_alloc_using_cc_common_link --@rules_rust//rust/settings:no_std=alloc +build:no_std_alloc_using_cc_common_link_and_mangled_alloc_symbols --config=no_std_alloc_using_cc_common_link +build:no_std_alloc_using_cc_common_link_and_mangled_alloc_symbols --@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols=True + + # Build with no_std + alloc build:no_std_alloc --@rules_rust//rust/toolchain/channel=nightly build:no_std_alloc --@rules_rust//rust/settings:no_std=alloc diff --git a/test/integration/no_std/MODULE.bazel b/test/integration/no_std/MODULE.bazel index d95c06162d..378a24efd8 100644 --- a/test/integration/no_std/MODULE.bazel +++ b/test/integration/no_std/MODULE.bazel @@ -10,15 +10,40 @@ local_path_override( ) bazel_dep(name = "rules_cc", version = "0.1.1") +bazel_dep(name = "platforms", version = "0.0.11") rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") rust.toolchain( edition = "2021", + target_settings = [ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_off", + ], versions = [ "nightly/2024-10-17", "1.82.0", ], ) + +# Generate a toolchain to be used for rust-based allocator symbols. + +# A recent enough version of rustc that mangles the internal allocator symbols. +VERSION = "nightly/2025-04-08" + +rust.repository_set( + name = "rust_with_alloc_mangling_linux_x86_64", + allocator_library = "@rules_rust//ffi/rs:empty", + edition = "2021", + exec_triple = "x86_64-unknown-linux-gnu", + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_settings = [ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_on", + ], + target_triple = "x86_64-unknown-linux-gnu", + versions = [VERSION], +) use_repo(rust, "rust_toolchains") register_toolchains("@rust_toolchains//:all") diff --git a/util/process_wrapper/BUILD.bazel b/util/process_wrapper/BUILD.bazel index 4c4ce05706..a946776e41 100644 --- a/util/process_wrapper/BUILD.bazel +++ b/util/process_wrapper/BUILD.bazel @@ -31,6 +31,10 @@ selects.config_setting_group( rust_binary_without_process_wrapper( name = "process_wrapper", srcs = glob(["*.rs"]), + allocator_libraries = select({ + "@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols_on": "@rules_rust//ffi/rs:allocator_libraries_with_mangling_support_without_process_wrapper", + "//conditions:default": "@rules_rust//ffi/rs:empty_allocator_libraries", + }), edition = "2018", # To ensure the process wrapper is produced deterministically # debug info, which is known to sometimes have host specific diff --git a/util/process_wrapper/BUILD.tinyjson.bazel b/util/process_wrapper/BUILD.tinyjson.bazel index f8013f6efd..7a7bcb3367 100644 --- a/util/process_wrapper/BUILD.tinyjson.bazel +++ b/util/process_wrapper/BUILD.tinyjson.bazel @@ -4,6 +4,7 @@ load("@rules_rust//rust/private:rust.bzl", "rust_library_without_process_wrapper rust_library_without_process_wrapper( name = "tinyjson", srcs = glob(["src/*.rs"]), + allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", edition = "2018", # To ensure the process wrapper is produced deterministically # debug info, which is known to sometimes have host specific