From 688e05b1f46d2f91b49aa31e5b9f4c8160be39a9 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Thu, 10 Apr 2025 07:48:01 +0000 Subject: [PATCH 01/19] add allocator libraries compatible with the new rustc mangling --- ffi/rs/BUILD.bazel | 34 ++++++++ ffi/rs/allocator_library/BUILD.bazel | 31 +++++++ ffi/rs/allocator_library/allocator_library.rs | 82 +++++++++++++++++++ ffi/rs/allocator_library/empty.rs | 0 rust/private/providers.bzl | 8 ++ rust/private/rust.bzl | 32 +++++++- rust/private/rustc.bzl | 33 +++++++- rust/settings/BUILD.bazel | 3 + rust/settings/settings.bzl | 17 ++++ rust/toolchain.bzl | 2 + .../.bazelrc | 42 ++++++++++ .../.gitignore | 2 + .../BUILD.bazel | 28 +++++++ .../MODULE.bazel | 48 +++++++++++ .../rustc_std_internal_symbol_mangling/dep.rs | 10 +++ .../test.cc | 7 ++ .../test.rs | 4 + util/process_wrapper/BUILD.bazel | 2 + util/process_wrapper/BUILD.tinyjson.bazel | 1 + 19 files changed, 382 insertions(+), 4 deletions(-) create mode 100644 ffi/rs/BUILD.bazel create mode 100644 ffi/rs/allocator_library/BUILD.bazel create mode 100644 ffi/rs/allocator_library/allocator_library.rs create mode 100644 ffi/rs/allocator_library/empty.rs create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.bazelrc create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs diff --git a/ffi/rs/BUILD.bazel b/ffi/rs/BUILD.bazel new file mode 100644 index 0000000000..4124e7d750 --- /dev/null +++ b/ffi/rs/BUILD.bazel @@ -0,0 +1,34 @@ +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", + # FIXME: 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"], +) + +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", + # FIXME: global_allocator_library + 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..2c25418645 --- /dev/null +++ b/ffi/rs/allocator_library/BUILD.bazel @@ -0,0 +1,31 @@ +load("@rules_rust//rust:defs.bzl", "rust_library") +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", + tags = ["manual"], +) + +rust_library_without_process_wrapper( + name = "allocator_library_without_process_wrapper", + srcs = srcs, + allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", + 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..57ef91d69e --- /dev/null +++ b/ffi/rs/allocator_library/allocator_library.rs @@ -0,0 +1,82 @@ +// 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. +#![no_std] +#![allow(warnings)] +#![allow(internal_features)] +#![feature(rustc_attrs)] +#![feature(linkage)] + +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!(); +} + +// 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/rust/private/providers.bzl b/rust/private/providers.bzl index 746370bc70..0ce4069ade 100644 --- a/rust/private/providers.bzl +++ b/rust/private/providers.bzl @@ -188,3 +188,11 @@ 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", + }, +) diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 74d458eef9..7112901672 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -17,7 +17,7 @@ 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", "AllocatorLibrariesInfo", "BuildInfo", "LintsInfo") load("//rust/private:rustc.bzl", "rustc_compile_action") load( "//rust/private:utils.bzl", @@ -719,6 +719,10 @@ _common_attrs = { doc = "A version to inject in the cargo environment variable.", default = "0.0.0", ), + "allocator_libraries": attr.label( + default = "//ffi/rs:default_allocator_libraries", + providers = [AllocatorLibrariesInfo], + ), "_stamp_flag": attr.label( doc = "A setting used to determine whether or not the `--stamp` flag is enabled", default = Label("//rust/private:stamp"), @@ -1573,6 +1577,32 @@ rust_library_group = rule( """), ) +def _rust_allocator_libraries_impl(ctx): + allocator_library = ctx.attr.allocator_library[CcInfo] if ctx.attr.allocator_library else None + global_allocator_library = ctx.attr.global_allocator_library[CcInfo] if ctx.attr.global_allocator_library else None + + providers = [AllocatorLibrariesInfo( + allocator_library = allocator_library, + global_allocator_library = global_allocator_library, + )] + + 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 = [CcInfo], + ), + "global_allocator_library": attr.label( + doc = "An optional library to provide when a default rust allocator is used.", + providers = [CcInfo], + ), + }, +) + 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..525cf7ed42 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", "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,43 @@ def _is_no_std(ctx, toolchain, crate_info): return False return True +def _merge_attr_and_toolchain_alloc_info(attr_alloc_cc_info, toolchain_alloc_cc_info): + if not attr_alloc_cc_info: + fail("empty attr_alloc_cc_info") + return cc_common.merge_cc_infos(cc_infos = [attr_alloc_cc_info, toolchain_alloc_cc_info]) + 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. + attr_alloc_libs = None + if hasattr(ctx.attr, "allocator_libraries"): + attr_alloc_libs = ctx.attr.allocator_libraries[AllocatorLibrariesInfo] if is_exec_configuration(ctx): + if attr_alloc_libs.allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.allocator_library, toolchain.libstd_no_allocator_ccinfo) return toolchain.libstd_and_allocator_ccinfo if toolchain._experimental_use_global_allocator: if _is_no_std(ctx, toolchain, crate_info): + if attr_alloc_libs.global_allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.global_allocator_library, toolchain.nostd_no_allocator_ccinfo) return toolchain.nostd_and_global_allocator_cc_info else: + if attr_alloc_libs.global_allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.global_allocator_library, toolchain.libstd_no_allocator_ccinfo) return toolchain.libstd_and_global_allocator_ccinfo - else: - return toolchain.libstd_and_allocator_ccinfo + if attr_alloc_libs.allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.allocator_library, toolchain.libstd_no_allocator_ccinfo) + return toolchain.libstd_and_allocator_ccinfo def _is_dylib(dep): return not bool(dep.static_library or dep.pic_static_library) diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index 8fb46461d8..8774b00fdb 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,8 @@ experimental_use_coverage_metadata_files() experimental_use_global_allocator() +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..ef830a7384 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -125,6 +125,23 @@ def experimental_use_global_allocator(): build_setting_default = False, ) +def experimental_use_allocator_libraries_with_mangled_symbols(): + """A flag used to select allocator libraries implemented in rust that are compatible with rustc's symbol mangling. + + This currently requires nightly rustc from 2025-04-05 or later. + """ + bool_flag( + name = "experimental_use_allocator_libraries_with_mangled_symbols", + build_setting_default = False, + ) + + native.config_setting( + name = "experimental_use_allocator_libraries_with_mangled_symbols_on", + flag_values = { + ":experimental_use_allocator_libraries_with_mangled_symbols": "true", + }, + ) + 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 91bc5455e9..7171803bf5 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -672,6 +672,8 @@ def _rust_toolchain_impl(ctx): 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_no_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, None, "std"), + nostd_no_allocator_cc_info = _make_libstd_and_allocator_ccinfo(ctx, rust_std, None, "no_std_with_alloc"), llvm_cov = ctx.file.llvm_cov, llvm_profdata = ctx.file.llvm_profdata, lto = lto, diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.bazelrc b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.bazelrc new file mode 100644 index 0000000000..44bf1ed56c --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.bazelrc @@ -0,0 +1,42 @@ +############################################################################### +## Bazel Configuration Flags +############################################################################### + +build --@rules_rust//rust/settings:experimental_use_cc_common_link=True +build --@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols=True + +############################################################################### + +# Enable rustfmt for all targets in the workspace +build:rustfmt --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect +build:rustfmt --output_groups=+rustfmt_checks + +# Enable clippy for all targets in the workspace +build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect +build:clippy --output_groups=+clippy_checks + +############################################################################### +## Incompatibility flags +############################################################################### + +# https://github.com/bazelbuild/bazel/issues/8195 +build --incompatible_disallow_empty_glob=true + +# https://github.com/bazelbuild/bazel/issues/12821 +build --nolegacy_external_runfiles + +# Required for cargo_build_script support before Bazel 7 +build --incompatible_merge_fixed_and_default_shell_env + +# https://github.com/bazelbuild/bazel/issues/23043. +build --incompatible_autoload_externally= + +############################################################################### +## Bzlmod +############################################################################### + +# A configuration for disabling bzlmod. +common:no-bzlmod --noenable_bzlmod --enable_workspace + +# Disable the bzlmod lockfile, so we don't accidentally commit MODULE.bazel.lock +common --lockfile_mode=off diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore new file mode 100644 index 0000000000..2f0f755d60 --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore @@ -0,0 +1,2 @@ +/bazel-* +/MODULE.bazel.lock diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel new file mode 100644 index 0000000000..eaa2138bcc --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel @@ -0,0 +1,28 @@ +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load( + "@rules_rust//rust:defs.bzl", + "rust_binary", + "rust_library", + "rust_shared_library", + "rust_test", +) + +rust_library( + name = "rsdep", + srcs = ["dep.rs"], +) + +rust_test( + name = "rstest", + srcs = ["test.rs"], + experimental_use_cc_common_link = 1, + deps = [ + ":rsdep", + ], +) + +cc_test( + name = "cctest", + srcs = ["test.cc"], + deps = [":rsdep"], +) diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel new file mode 100644 index 0000000000..f019e43a62 --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel @@ -0,0 +1,48 @@ +# Repository setup to validate rules_rust with rustc that mangles rustc_std_internal_symbols. +# +# To support linking rust code into non-rust contexts, we must provide +# implementations of the default internal rust allocator symbols, e.g.: +# https://github.com/bazelbuild/rules_rust/blob/main/ffi/cc/allocator_library/allocator_library.cc +# +# Recent versions of rustc started to mangle these internal symbols, +# rendering our c++ implementations ineffective: +# https://github.com/rust-lang/rust/pull/127173 +module( + name = "rules_rust_test_cc_common_link_rustc_std_internal_symbol_mangling", + version = "0.0.0", +) + +bazel_dep(name = "rules_rust", version = "0.0.0") +local_path_override( + module_name = "rules_rust", + path = "../../../..", +) + +bazel_dep(name = "rules_cc", version = "0.1.1") +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "platforms", version = "0.0.11") + +rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") + +# A recent enough version of rustc that mangles the internal allocator symbols. +VERSION = "nightly/2025-04-08" + +rust.toolchain( + versions = [VERSION], +) +rust.repository_set( + name = "rust_linux_x86_64", + allocator_library = "@rules_rust//ffi/rs:empty", + edition = "2021", + exec_triple = "x86_64-unknown-linux-gnu", + #global_allocator_library = "", + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_triple = "x86_64-unknown-linux-gnu", + versions = [VERSION], +) +use_repo(rust, "rust_toolchains") + +register_toolchains("@rust_toolchains//:all") diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs new file mode 100644 index 0000000000..3ed213f810 --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs @@ -0,0 +1,10 @@ +#[no_mangle] +pub extern "C" fn rdep() -> i32 { + let mut v = vec![1, 2, 3]; + while v.len() < 1000 { + let n = v.len(); + v.push(v[n-1] + v[n-2]); + v.push(v[n-3]); + } + return v.len().try_into().unwrap(); +} diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc new file mode 100644 index 0000000000..6974d968f9 --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc @@ -0,0 +1,7 @@ +#include + +extern "C" int rdep(); + +int main() { + printf("%d\n", rdep()); +} diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs new file mode 100644 index 0000000000..7f433b89f7 --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs @@ -0,0 +1,4 @@ +#[test] +fn test() { + assert_eq!(1001, rsdep::rdep()); +} diff --git a/util/process_wrapper/BUILD.bazel b/util/process_wrapper/BUILD.bazel index 4c4ce05706..53963db826 100644 --- a/util/process_wrapper/BUILD.bazel +++ b/util/process_wrapper/BUILD.bazel @@ -31,7 +31,9 @@ selects.config_setting_group( rust_binary_without_process_wrapper( name = "process_wrapper", srcs = glob(["*.rs"]), + allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", edition = "2018", + experimental_use_cc_common_link = 0, # To ensure the process wrapper is produced deterministically # debug info, which is known to sometimes have host specific # paths embedded in this section, is stripped out. 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 From 97d65c669466d03827e1eb2c926be3534961f18d Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Thu, 10 Apr 2025 08:02:47 +0000 Subject: [PATCH 02/19] fixes --- ffi/rs/allocator_library/BUILD.bazel | 2 ++ ffi/rs/allocator_library/allocator_library.rs | 2 +- rust/private/rustc.bzl | 22 ++++++++++--------- .../BUILD.bazel | 4 +--- util/process_wrapper/BUILD.bazel | 3 +-- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ffi/rs/allocator_library/BUILD.bazel b/ffi/rs/allocator_library/BUILD.bazel index 2c25418645..ee02f97db4 100644 --- a/ffi/rs/allocator_library/BUILD.bazel +++ b/ffi/rs/allocator_library/BUILD.bazel @@ -20,6 +20,7 @@ rust_library( name = "allocator_library", srcs = srcs, allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", + edition = "2024", tags = ["manual"], ) @@ -27,5 +28,6 @@ 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 index 57ef91d69e..b332b247ef 100644 --- a/ffi/rs/allocator_library/allocator_library.rs +++ b/ffi/rs/allocator_library/allocator_library.rs @@ -19,7 +19,7 @@ #![feature(rustc_attrs)] #![feature(linkage)] -extern "C" { +unsafe extern "C" { #[rustc_std_internal_symbol] fn __rdl_alloc(size: usize, align: usize) -> *mut u8; diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 525cf7ed42..247fc98e2e 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1622,24 +1622,26 @@ def _get_std_and_alloc_info(ctx, toolchain, crate_info): # # When provided, the allocator_libraries attribute takes precedence over the # toolchain allocator attributes. - attr_alloc_libs = None + attr_allocator_library = None + attr_global_allocator_library = None if hasattr(ctx.attr, "allocator_libraries"): - attr_alloc_libs = ctx.attr.allocator_libraries[AllocatorLibrariesInfo] + attr_allocator_library = ctx.attr.allocator_libraries[AllocatorLibrariesInfo].allocator_library + attr_global_allocator_library = ctx.attr.allocator_libraries[AllocatorLibrariesInfo].global_allocator_library if is_exec_configuration(ctx): - if attr_alloc_libs.allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.allocator_library, toolchain.libstd_no_allocator_ccinfo) + if attr_allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_allocator_library, toolchain.libstd_no_allocator_ccinfo) return toolchain.libstd_and_allocator_ccinfo if toolchain._experimental_use_global_allocator: if _is_no_std(ctx, toolchain, crate_info): - if attr_alloc_libs.global_allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.global_allocator_library, toolchain.nostd_no_allocator_ccinfo) + if attr_global_allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_global_allocator_library, toolchain.nostd_no_allocator_ccinfo) return toolchain.nostd_and_global_allocator_cc_info else: - if attr_alloc_libs.global_allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.global_allocator_library, toolchain.libstd_no_allocator_ccinfo) + if attr_global_allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_global_allocator_library, toolchain.libstd_no_allocator_ccinfo) return toolchain.libstd_and_global_allocator_ccinfo - if attr_alloc_libs.allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_alloc_libs.allocator_library, toolchain.libstd_no_allocator_ccinfo) + if attr_allocator_library: + return _merge_attr_and_toolchain_alloc_info(attr_allocator_library, toolchain.libstd_no_allocator_ccinfo) return toolchain.libstd_and_allocator_ccinfo def _is_dylib(dep): diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel index eaa2138bcc..74fa11b7d8 100644 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel @@ -1,9 +1,7 @@ -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load("@rules_cc//cc:defs.bzl", "cc_test") load( "@rules_rust//rust:defs.bzl", - "rust_binary", "rust_library", - "rust_shared_library", "rust_test", ) diff --git a/util/process_wrapper/BUILD.bazel b/util/process_wrapper/BUILD.bazel index 53963db826..381680ed9e 100644 --- a/util/process_wrapper/BUILD.bazel +++ b/util/process_wrapper/BUILD.bazel @@ -31,9 +31,8 @@ selects.config_setting_group( rust_binary_without_process_wrapper( name = "process_wrapper", srcs = glob(["*.rs"]), - allocator_libraries = "@rules_rust//ffi/rs:empty_allocator_libraries", + allocator_libraries = "@rules_rust//ffi/rs:allocator_libraries_with_mangling_support_without_process_wrapper", edition = "2018", - experimental_use_cc_common_link = 0, # To ensure the process wrapper is produced deterministically # debug info, which is known to sometimes have host specific # paths embedded in this section, is stripped out. From 09ef05273b061d47f9c1fbe185d31bccfcb2150c Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Thu, 10 Apr 2025 10:01:29 +0000 Subject: [PATCH 03/19] fixes --- .../rustc_std_internal_symbol_mangling/WORKSPACE.bazel | 1 + .../cc_common_link/rustc_std_internal_symbol_mangling/dep.rs | 5 ++++- .../rustc_std_internal_symbol_mangling/test.cc | 5 ++++- util/process_wrapper/BUILD.bazel | 5 ++++- 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel new file mode 100644 index 0000000000..c29b7e548f --- /dev/null +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel @@ -0,0 +1 @@ +workspace(name = "rules_rust_test_cc_common_link_rustc_std_internal_symbol_mangling") diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs index 3ed213f810..c690c08b14 100644 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs @@ -1,10 +1,13 @@ #[no_mangle] pub extern "C" fn rdep() -> i32 { + // Just some logic complicated enough to require heap + // allocations. + use std::convert::TryInto; let mut v = vec![1, 2, 3]; while v.len() < 1000 { let n = v.len(); v.push(v[n-1] + v[n-2]); v.push(v[n-3]); } - return v.len().try_into().unwrap(); + return v.len().try_into().unwrap(); // returns 1001 } diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc index 6974d968f9..0cf2e6b27a 100644 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc @@ -3,5 +3,8 @@ extern "C" int rdep(); int main() { - printf("%d\n", rdep()); + if (rdep() != 1001) { + return 1; + } + return 0; } diff --git a/util/process_wrapper/BUILD.bazel b/util/process_wrapper/BUILD.bazel index 381680ed9e..a946776e41 100644 --- a/util/process_wrapper/BUILD.bazel +++ b/util/process_wrapper/BUILD.bazel @@ -31,7 +31,10 @@ selects.config_setting_group( rust_binary_without_process_wrapper( name = "process_wrapper", srcs = glob(["*.rs"]), - allocator_libraries = "@rules_rust//ffi/rs:allocator_libraries_with_mangling_support_without_process_wrapper", + 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 From aef67c7f67eff6099d52492421f569290452ebdf Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 11 Apr 2025 10:00:39 +0000 Subject: [PATCH 04/19] add global alloc support and tests --- ffi/rs/BUILD.bazel | 7 ++- ffi/rs/allocator_library/allocator_library.rs | 4 ++ ffi/rs/global_allocator_library/BUILD.bazel | 25 ++++++++++ ffi/rs/global_allocator_library/empty.rs | 0 .../global_allocator_library.rs | 48 +++++++++++++++++++ .../BUILD.bazel | 1 - .../.bazelrc | 43 +++++++++++++++++ .../BUILD.bazel | 17 +++++++ .../MODULE.bazel | 37 ++++++++++++++ .../WORKSPACE.bazel | 1 + .../bazel-bin | 1 + .../bazel-out | 1 + .../bazel-rustc_std_internal_symbol_mangling | 1 + .../bazel-testlogs | 1 + .../main.rs | 46 ++++++++++++++++++ 15 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 ffi/rs/global_allocator_library/BUILD.bazel create mode 100644 ffi/rs/global_allocator_library/empty.rs create mode 100644 ffi/rs/global_allocator_library/global_allocator_library.rs create mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc create mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel create mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel create mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel create mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin create mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out create mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling create mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs create mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs diff --git a/ffi/rs/BUILD.bazel b/ffi/rs/BUILD.bazel index 4124e7d750..dd5e8f0f86 100644 --- a/ffi/rs/BUILD.bazel +++ b/ffi/rs/BUILD.bazel @@ -3,7 +3,7 @@ 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", - # FIXME: global_allocator_library + global_allocator_library = "@rules_rust//ffi/rs/global_allocator_library", visibility = ["//visibility:public"], ) @@ -26,9 +26,12 @@ cc_library( 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", - # FIXME: global_allocator_library + # 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/allocator_library.rs b/ffi/rs/allocator_library/allocator_library.rs index b332b247ef..fb498d81d7 100644 --- a/ffi/rs/allocator_library/allocator_library.rs +++ b/ffi/rs/allocator_library/allocator_library.rs @@ -13,6 +13,9 @@ // 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)] @@ -71,6 +74,7 @@ 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] diff --git a/ffi/rs/global_allocator_library/BUILD.bazel b/ffi/rs/global_allocator_library/BUILD.bazel new file mode 100644 index 0000000000..adbe884396 --- /dev/null +++ b/ffi/rs/global_allocator_library/BUILD.bazel @@ -0,0 +1,25 @@ +load("@rules_rust//rust:defs.bzl", "rust_library") +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 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/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel index 74fa11b7d8..6bcad908eb 100644 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel @@ -13,7 +13,6 @@ rust_library( rust_test( name = "rstest", srcs = ["test.rs"], - experimental_use_cc_common_link = 1, deps = [ ":rsdep", ], diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc new file mode 100644 index 0000000000..a09e927526 --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc @@ -0,0 +1,43 @@ +############################################################################### +## Bazel Configuration Flags +############################################################################### + +build --@rules_rust//rust/settings:experimental_use_cc_common_link=True +build --@rules_rust//rust/settings:experimental_use_global_allocator=True +build --@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols=True + +############################################################################### + +# Enable rustfmt for all targets in the workspace +build:rustfmt --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect +build:rustfmt --output_groups=+rustfmt_checks + +# Enable clippy for all targets in the workspace +build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect +build:clippy --output_groups=+clippy_checks + +############################################################################### +## Incompatibility flags +############################################################################### + +# https://github.com/bazelbuild/bazel/issues/8195 +build --incompatible_disallow_empty_glob=true + +# https://github.com/bazelbuild/bazel/issues/12821 +build --nolegacy_external_runfiles + +# Required for cargo_build_script support before Bazel 7 +build --incompatible_merge_fixed_and_default_shell_env + +# https://github.com/bazelbuild/bazel/issues/23043. +build --incompatible_autoload_externally= + +############################################################################### +## Bzlmod +############################################################################### + +# A configuration for disabling bzlmod. +common:no-bzlmod --noenable_bzlmod --enable_workspace + +# Disable the bzlmod lockfile, so we don't accidentally commit MODULE.bazel.lock +common --lockfile_mode=off diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel new file mode 100644 index 0000000000..d037a22e52 --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel @@ -0,0 +1,17 @@ +load( + "@rules_rust//rust:defs.bzl", + "rust_binary", + "rust_test", +) + +rust_binary( + name = "main", + srcs = ["main.rs"], + edition = "2021", +) + +rust_test( + name = "global_alloc_test", + crate = ":main", + edition = "2021", +) diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel new file mode 100644 index 0000000000..330e590007 --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel @@ -0,0 +1,37 @@ +module( + name = "rules_rust_test_cc_common_link_with_global_alloc_rustc_std_internal_symbol_mangling", + version = "0.0.0", +) + +bazel_dep(name = "rules_rust", version = "0.0.0") +local_path_override( + module_name = "rules_rust", + path = "../../../..", +) + +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") + +# A recent enough version of rustc that mangles the internal allocator symbols. +VERSION = "nightly/2025-04-08" + +rust.toolchain( + versions = [VERSION], +) +rust.repository_set( + name = "rust_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_triple = "x86_64-unknown-linux-gnu", + versions = [VERSION], +) +use_repo(rust, "rust_toolchains") + +register_toolchains("@rust_toolchains//:all") diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel new file mode 100644 index 0000000000..571df760ab --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel @@ -0,0 +1 @@ +workspace(name = "rules_rust_test_cc_common_link_with_global_alloc_rustc_std_internal_symbol_mangling") diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin new file mode 120000 index 0000000000..c4a512a4ab --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin @@ -0,0 +1 @@ +/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main/bazel-out/k8-fastbuild/bin \ No newline at end of file diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out new file mode 120000 index 0000000000..26d54958ed --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out @@ -0,0 +1 @@ +/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main/bazel-out \ No newline at end of file diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling new file mode 120000 index 0000000000..276d865d02 --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling @@ -0,0 +1 @@ +/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main \ No newline at end of file diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs new file mode 120000 index 0000000000..ba4f7a6077 --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs @@ -0,0 +1 @@ +/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main/bazel-out/k8-fastbuild/testlogs \ No newline at end of file diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs new file mode 100644 index 0000000000..79dccff40f --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs @@ -0,0 +1,46 @@ +use std::alloc::{GlobalAlloc, Layout, System}; +use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; + +static ALLOCATED: AtomicUsize = AtomicUsize::new(0); + +struct MyAllocator; + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + let ret = System.alloc(layout); + if !ret.is_null() { + ALLOCATED.fetch_add(layout.size(), SeqCst); + } + ret + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + System.dealloc(ptr, layout); + ALLOCATED.fetch_sub(layout.size(), SeqCst); + } +} + +#[global_allocator] +static GLOBAL: MyAllocator = MyAllocator; + +fn main() { + println!("allocated bytes before main: {}", ALLOCATED.load(SeqCst)); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_global_alloc_was_used() { + // Allocated bytes before main + let bytes_start = ALLOCATED.load(SeqCst); + + let _x = Box::new(5); // 4 bytes + let _y = Box::new(true); // 1 byte + + let bytes_end = ALLOCATED.load(SeqCst); + + assert_eq!(bytes_end - bytes_start, 5); + } +} From 2c20ec442654523356e051e5b1b12faae65b742d Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 15 Apr 2025 14:10:14 +0000 Subject: [PATCH 05/19] add a way to control rustc allocator libraries feature per-toolchain --- ffi/rs/BUILD.bazel | 3 +++ ffi/rs/allocator_library/BUILD.bazel | 2 ++ ffi/rs/global_allocator_library/BUILD.bazel | 4 ---- rust/private/rust.bzl | 11 ++++++---- rust/private/rustc.bzl | 10 ++++++++- rust/settings/BUILD.bazel | 4 +++- rust/settings/settings.bzl | 8 ++++--- rust/toolchain.bzl | 23 +++++++++++++++++++++ 8 files changed, 52 insertions(+), 13 deletions(-) diff --git a/ffi/rs/BUILD.bazel b/ffi/rs/BUILD.bazel index dd5e8f0f86..1fb2abebec 100644 --- a/ffi/rs/BUILD.bazel +++ b/ffi/rs/BUILD.bazel @@ -1,3 +1,6 @@ +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( diff --git a/ffi/rs/allocator_library/BUILD.bazel b/ffi/rs/allocator_library/BUILD.bazel index ee02f97db4..76a776c13e 100644 --- a/ffi/rs/allocator_library/BUILD.bazel +++ b/ffi/rs/allocator_library/BUILD.bazel @@ -1,4 +1,6 @@ load("@rules_rust//rust:defs.bzl", "rust_library") + +# buildifier: disable=bzl-visibility load( "@rules_rust//rust/private:rust.bzl", "rust_library_without_process_wrapper", diff --git a/ffi/rs/global_allocator_library/BUILD.bazel b/ffi/rs/global_allocator_library/BUILD.bazel index adbe884396..743c98d334 100644 --- a/ffi/rs/global_allocator_library/BUILD.bazel +++ b/ffi/rs/global_allocator_library/BUILD.bazel @@ -1,8 +1,4 @@ load("@rules_rust//rust:defs.bzl", "rust_library") -load( - "@rules_rust//rust/private:rust.bzl", - "rust_library_without_process_wrapper", -) package( default_visibility = ["@rules_rust//ffi/rs:__subpackages__"], diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 7112901672..54d6c10917 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -528,6 +528,13 @@ def _stamp_attribute(default_value): # Internal attributes core to Rustc actions. RUSTC_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], + ), "_error_format": attr.label( default = Label("//rust/settings:error_format"), ), @@ -719,10 +726,6 @@ _common_attrs = { doc = "A version to inject in the cargo environment variable.", default = "0.0.0", ), - "allocator_libraries": attr.label( - default = "//ffi/rs:default_allocator_libraries", - providers = [AllocatorLibrariesInfo], - ), "_stamp_flag": attr.label( doc = "A setting used to determine whether or not the `--stamp` flag is enabled", default = Label("//rust/private:stamp"), diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 247fc98e2e..b580862742 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1609,6 +1609,14 @@ def _merge_attr_and_toolchain_alloc_info(attr_alloc_cc_info, toolchain_alloc_cc_ fail("empty attr_alloc_cc_info") return cc_common.merge_cc_infos(cc_infos = [attr_alloc_cc_info, toolchain_alloc_cc_info]) +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. # @@ -1624,7 +1632,7 @@ def _get_std_and_alloc_info(ctx, toolchain, crate_info): # toolchain allocator attributes. attr_allocator_library = None attr_global_allocator_library = None - if hasattr(ctx.attr, "allocator_libraries"): + if _should_use_rustc_allocator_libraries(toolchain) and hasattr(ctx.attr, "allocator_libraries"): attr_allocator_library = ctx.attr.allocator_libraries[AllocatorLibrariesInfo].allocator_library attr_global_allocator_library = ctx.attr.allocator_libraries[AllocatorLibrariesInfo].global_allocator_library if is_exec_configuration(ctx): diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index 8774b00fdb..d24237a078 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -72,7 +72,9 @@ experimental_use_coverage_metadata_files() experimental_use_global_allocator() -experimental_use_allocator_libraries_with_mangled_symbols() +experimental_use_allocator_libraries_with_mangled_symbols( + name = "experimental_use_allocator_libraries_with_mangled_symbols", +) experimental_use_sh_toolchain_for_bootstrap_process_wrapper() diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index ef830a7384..355d526112 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -125,18 +125,20 @@ def experimental_use_global_allocator(): build_setting_default = False, ) -def experimental_use_allocator_libraries_with_mangled_symbols(): +def experimental_use_allocator_libraries_with_mangled_symbols(name): """A flag used to select allocator libraries implemented in rust that are compatible with rustc's symbol mangling. + Also a corresponding config setting that can be used in selects(). + This currently requires nightly rustc from 2025-04-05 or later. """ bool_flag( - name = "experimental_use_allocator_libraries_with_mangled_symbols", + name = name, build_setting_default = False, ) native.config_setting( - name = "experimental_use_allocator_libraries_with_mangled_symbols_on", + name = "%s_on" % name, flag_values = { ":experimental_use_allocator_libraries_with_mangled_symbols": "true", }, diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 7171803bf5..b383131422 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -711,6 +711,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, @@ -785,6 +787,19 @@ rust_toolchain = rule( 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.", ), + "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, + ), "extra_exec_rustc_flags": attr.string_list( doc = "Extra flags to pass to rustc in exec configuration", ), @@ -899,6 +914,14 @@ rust_toolchain = rule( "This flag is only relevant when used together with --@rules_rust//rust/settings:experimental_use_global_allocator." ), ), + "_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." + ), + ), "_incompatible_change_rust_test_compilation_output_directory": attr.label( default = Label("//rust/settings:incompatible_change_rust_test_compilation_output_directory"), ), From fdfa08e4fbbbfebf2ab33a30cfe7bc3bf074f877 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 15 Apr 2025 14:19:04 +0000 Subject: [PATCH 06/19] add to its own attribute dict --- rust/private/rust.bzl | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 54d6c10917..86bd23d867 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -528,13 +528,6 @@ def _stamp_attribute(default_value): # Internal attributes core to Rustc actions. RUSTC_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], - ), "_error_format": attr.label( default = Label("//rust/settings:error_format"), ), @@ -571,6 +564,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("""\ @@ -730,7 +736,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( From bc47c49a2bee12d9a4b0da3475c02f4edf77104a Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 15 Apr 2025 14:37:33 +0000 Subject: [PATCH 07/19] formatting --- rust/toolchain.bzl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index b383131422..5240982202 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -783,10 +783,6 @@ 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_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.", - ), "experimental_use_allocator_libraries_with_mangled_symbols": attr.int( doc = ( "Whether to use rust-based allocator libraries with " + @@ -800,6 +796,10 @@ rust_toolchain = rule( 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.", + ), "extra_exec_rustc_flags": attr.string_list( doc = "Extra flags to pass to rustc in exec configuration", ), @@ -907,13 +907,6 @@ rust_toolchain = rule( "_experimental_use_coverage_metadata_files": attr.label( default = Label("//rust/settings:experimental_use_coverage_metadata_files"), ), - "_experimental_use_global_allocator": attr.label( - default = Label("//rust/settings:experimental_use_global_allocator"), - doc = ( - "Label to a boolean build setting that informs the target build whether a global allocator is being used." + - "This flag is only relevant when used together with --@rules_rust//rust/settings:experimental_use_global_allocator." - ), - ), "_experimental_use_allocator_libraries_with_mangled_symbols_setting": attr.label( default = Label("//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols"), providers = [BuildSettingInfo], @@ -922,6 +915,13 @@ rust_toolchain = rule( "allocator libraries that mangle symbols." ), ), + "_experimental_use_global_allocator": attr.label( + default = Label("//rust/settings:experimental_use_global_allocator"), + doc = ( + "Label to a boolean build setting that informs the target build whether a global allocator is being used." + + "This flag is only relevant when used together with --@rules_rust//rust/settings:experimental_use_global_allocator." + ), + ), "_incompatible_change_rust_test_compilation_output_directory": attr.label( default = Label("//rust/settings:incompatible_change_rust_test_compilation_output_directory"), ), From 34770cb6fb4d6ba849395920bb741be3ead8fa90 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 15 Apr 2025 14:39:24 +0000 Subject: [PATCH 08/19] formatting --- rust/toolchain.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 5240982202..dca8e2ae94 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -904,9 +904,6 @@ rust_toolchain = rule( "_codegen_units": attr.label( default = Label("//rust/settings:codegen_units"), ), - "_experimental_use_coverage_metadata_files": attr.label( - default = Label("//rust/settings:experimental_use_coverage_metadata_files"), - ), "_experimental_use_allocator_libraries_with_mangled_symbols_setting": attr.label( default = Label("//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols"), providers = [BuildSettingInfo], @@ -915,6 +912,9 @@ rust_toolchain = rule( "allocator libraries that mangle symbols." ), ), + "_experimental_use_coverage_metadata_files": attr.label( + default = Label("//rust/settings:experimental_use_coverage_metadata_files"), + ), "_experimental_use_global_allocator": attr.label( default = Label("//rust/settings:experimental_use_global_allocator"), doc = ( From 911f87711faf09871f139bae37065b1deca9ba3b Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 15 Apr 2025 14:51:48 +0000 Subject: [PATCH 09/19] reformat --- .../rustc_std_internal_symbol_mangling/test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc index 0cf2e6b27a..ce13d7801d 100644 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc +++ b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc @@ -3,8 +3,8 @@ extern "C" int rdep(); int main() { - if (rdep() != 1001) { - return 1; - } - return 0; + if (rdep() != 1001) { + return 1; + } + return 0; } From 161c960741205e71834ffde6a4972b03edf1713a Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Mon, 28 Apr 2025 16:09:20 +0000 Subject: [PATCH 10/19] add nostd test and fix --- rust/private/rustc.bzl | 2 +- rust/toolchain.bzl | 4 +- .../.gitignore | 2 + .../bazel-bin | 1 - .../bazel-out | 1 - .../bazel-rustc_std_internal_symbol_mangling | 1 - .../bazel-testlogs | 1 - .../.bazelrc | 93 +++++++++++++++++++ .../.gitignore | 2 + .../BUILD.bazel | 47 ++++++++++ .../MODULE.bazel | 46 +++++++++ .../WORKSPACE.bazel | 1 + .../alloc.rs | 6 ++ .../rustc_std_internal_symbol_mangling/lib.rs | 22 +++++ .../rustc_std_internal_symbol_mangling/main.c | 9 ++ .../main.rs | 38 ++++++++ .../no_std.rs | 16 ++++ 17 files changed, 285 insertions(+), 7 deletions(-) create mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore delete mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin delete mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out delete mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling delete mode 120000 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/.bazelrc create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/.gitignore create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/BUILD.bazel create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/MODULE.bazel create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/WORKSPACE.bazel create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/alloc.rs create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/lib.rs create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/main.c create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/main.rs create mode 100644 test/integration/no_std/rustc_std_internal_symbol_mangling/no_std.rs diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index b580862742..6867fd8d68 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1643,7 +1643,7 @@ def _get_std_and_alloc_info(ctx, toolchain, crate_info): if _is_no_std(ctx, toolchain, crate_info): if attr_global_allocator_library: return _merge_attr_and_toolchain_alloc_info(attr_global_allocator_library, toolchain.nostd_no_allocator_ccinfo) - return toolchain.nostd_and_global_allocator_cc_info + return toolchain.nostd_and_global_allocator_ccinfo else: if attr_global_allocator_library: return _merge_attr_and_toolchain_alloc_info(attr_global_allocator_library, toolchain.libstd_no_allocator_ccinfo) diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index dca8e2ae94..eb7c585658 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -671,9 +671,9 @@ def _rust_toolchain_impl(ctx): 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"), + nostd_and_global_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, ctx.attr.global_allocator_library, "no_std_with_alloc"), libstd_no_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, None, "std"), - nostd_no_allocator_cc_info = _make_libstd_and_allocator_ccinfo(ctx, rust_std, None, "no_std_with_alloc"), + nostd_no_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, None, "no_std_with_alloc"), llvm_cov = ctx.file.llvm_cov, llvm_profdata = ctx.file.llvm_profdata, lto = lto, diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore new file mode 100644 index 0000000000..2f0f755d60 --- /dev/null +++ b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore @@ -0,0 +1,2 @@ +/bazel-* +/MODULE.bazel.lock diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin deleted file mode 120000 index c4a512a4ab..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-bin +++ /dev/null @@ -1 +0,0 @@ -/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main/bazel-out/k8-fastbuild/bin \ No newline at end of file diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out deleted file mode 120000 index 26d54958ed..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-out +++ /dev/null @@ -1 +0,0 @@ -/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main/bazel-out \ No newline at end of file diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling deleted file mode 120000 index 276d865d02..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-rustc_std_internal_symbol_mangling +++ /dev/null @@ -1 +0,0 @@ -/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main \ No newline at end of file diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs deleted file mode 120000 index ba4f7a6077..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/bazel-testlogs +++ /dev/null @@ -1 +0,0 @@ -/usr/local/google/home/krasimir/.cache/bazel/_bazel_krasimir/f8d75f959225228e014305ed4d8474b1/execroot/_main/bazel-out/k8-fastbuild/testlogs \ No newline at end of file diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/.bazelrc b/test/integration/no_std/rustc_std_internal_symbol_mangling/.bazelrc new file mode 100644 index 0000000000..887352ed0f --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/.bazelrc @@ -0,0 +1,93 @@ +############################################################################### +## Bazel Configuration Flags +## +## `.bazelrc` is a Bazel configuration file. +## https://bazel.build/docs/best-practices#bazelrc-file +############################################################################### + +# Build with no_std + alloc using cc_common.link infrastructure for linking +build:no_std_alloc_using_cc_common_link --@rules_rust//rust/toolchain/channel=nightly +build:no_std_alloc_using_cc_common_link --@rules_rust//rust/settings:experimental_use_cc_common_link=True +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 --@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 + +############################################################################### + +# https://bazel.build/reference/command-line-reference#flag--enable_platform_specific_config +common --enable_platform_specific_config + +# Enable the only currently supported report type +# https://bazel.build/reference/command-line-reference#flag--combined_report +coverage --combined_report=lcov + +# Avoid fully cached builds reporting no coverage and failing CI +# https://bazel.build/reference/command-line-reference#flag--experimental_fetch_all_coverage_outputs +coverage --experimental_fetch_all_coverage_outputs + +# Required for some of the tests +# https://bazel.build/reference/command-line-reference#flag--experimental_cc_shared_library +common --experimental_cc_shared_library + +############################################################################### +## Unique configuration groups +############################################################################### + +# Enable use of the nightly toolchains. +build:nightly --@rules_rust//rust/toolchain/channel=nightly + +# Enable rustfmt for all targets in the workspace +build:rustfmt --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect +build:rustfmt --output_groups=+rustfmt_checks + +# Enable clippy for all targets in the workspace +build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect +build:clippy --output_groups=+clippy_checks + +# Enable unpretty for all targets in the workspace +build:unpretty --aspects=@rules_rust//rust:defs.bzl%rust_unpretty_aspect +build:unpretty --output_groups=+rust_unpretty + +# `unpretty` requires the nightly toolchain. See tracking issue: +# https://github.com/rust-lang/rust/issues/43364 +build:unpretty --config=nightly + +############################################################################### +## Incompatibility flags +############################################################################### + +# https://github.com/bazelbuild/bazel/issues/8195 +build --incompatible_disallow_empty_glob=true + +# https://github.com/bazelbuild/bazel/issues/12821 +build --nolegacy_external_runfiles + +# Required for cargo_build_script support before Bazel 7 +build --incompatible_merge_fixed_and_default_shell_env + +# https://github.com/bazelbuild/bazel/issues/23043. +build --incompatible_autoload_externally= + +############################################################################### +## Bzlmod +############################################################################### + +# A configuration for disabling bzlmod. +common:no-bzlmod --noenable_bzlmod --enable_workspace + +# Disable the bzlmod lockfile, so we don't accidentally commit MODULE.bazel.lock +common --lockfile_mode=off + +############################################################################### +## Custom user flags +## +## This should always be the last thing in the `.bazelrc` file to ensure +## consistent behavior when setting flags in that file as `.bazelrc` files are +## evaluated top to bottom. +############################################################################### + +try-import %workspace%/user.bazelrc diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/.gitignore b/test/integration/no_std/rustc_std_internal_symbol_mangling/.gitignore new file mode 100644 index 0000000000..2f0f755d60 --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/.gitignore @@ -0,0 +1,2 @@ +/bazel-* +/MODULE.bazel.lock diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/no_std/rustc_std_internal_symbol_mangling/BUILD.bazel new file mode 100644 index 0000000000..cc90de45ec --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/BUILD.bazel @@ -0,0 +1,47 @@ +load("@no_std_crate_index//:defs.bzl", "aliases", "all_crate_deps") +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load( + "@rules_rust//rust:defs.bzl", + "rust_binary", + "rust_library", + "rust_shared_library", +) + +rust_shared_library( + name = "lib", + srcs = [ + "lib.rs", + "no_std.rs", + ], + crate_features = select({ + "@rules_rust//rust/settings:is_no_std": [], + "//conditions:default": ["std"], + }), + edition = "2021", + deps = ["custom_alloc"], +) + +rust_library( + name = "custom_alloc", + srcs = ["alloc.rs"], + aliases = aliases(), + deps = all_crate_deps(normal = True), +) + +cc_library( + name = "nostartfiles", + linkopts = ["-nostartfiles"], +) + +rust_binary( + name = "main", + srcs = ["main.rs"], + aliases = aliases(), + deps = all_crate_deps(normal = True) + [":nostartfiles"], +) + +cc_test( + name = "no_std_cc_test", + srcs = ["main.c"], + deps = [":lib"], +) diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/MODULE.bazel b/test/integration/no_std/rustc_std_internal_symbol_mangling/MODULE.bazel new file mode 100644 index 0000000000..444136f22d --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/MODULE.bazel @@ -0,0 +1,46 @@ +module( + name = "rules_rust_test_no_std_rustc_std_internal_symbol_mangling", + version = "0.0.0", +) + +bazel_dep(name = "rules_rust", version = "0.0.0") +local_path_override( + module_name = "rules_rust", + path = "../../../..", +) + +bazel_dep(name = "rules_cc", version = "0.1.1") +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "platforms", version = "0.0.11") + +rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") + +# A recent enough version of rustc that mangles the internal allocator symbols. +VERSION = "nightly/2025-04-08" + +rust.toolchain( + versions = [VERSION], +) +rust.repository_set( + name = "rust_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_triple = "x86_64-unknown-linux-gnu", + versions = [VERSION], +) +use_repo(rust, "rust_toolchains") + +register_toolchains("@rust_toolchains//:all") + +crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate") +crate.spec( + package = "libc_alloc", + version = "1.0.3", +) +crate.from_specs(name = "no_std_crate_index") +use_repo(crate, "no_std_crate_index") diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/WORKSPACE.bazel b/test/integration/no_std/rustc_std_internal_symbol_mangling/WORKSPACE.bazel new file mode 100644 index 0000000000..0a53422387 --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/WORKSPACE.bazel @@ -0,0 +1 @@ +workspace(name = "rules_rust_test_no_std_rustc_std_internal_symbol_mangling") diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/alloc.rs b/test/integration/no_std/rustc_std_internal_symbol_mangling/alloc.rs new file mode 100644 index 0000000000..3cead000a3 --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/alloc.rs @@ -0,0 +1,6 @@ +#![no_std] + +use libc_alloc::LibcAlloc; + +#[global_allocator] +static ALLOCATOR: LibcAlloc = LibcAlloc; diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/lib.rs b/test/integration/no_std/rustc_std_internal_symbol_mangling/lib.rs new file mode 100644 index 0000000000..03647155f7 --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/lib.rs @@ -0,0 +1,22 @@ +#![no_std] +// These features are needed to support no_std + alloc +#![feature(lang_items)] +#![feature(alloc_error_handler)] +#![feature(core_intrinsics)] +#![allow(unused_imports)] +use custom_alloc; + +#[cfg(all(not(feature = "std"), not(test)))] +mod no_std; + +#[cfg(not(feature = "std"))] +#[no_mangle] +pub extern "C" fn return_5_in_no_std() -> i32 { + 5 +} + +#[cfg(feature = "std")] +#[no_mangle] +pub extern "C" fn return_5_in_no_std() -> i32 { + 6 +} diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/main.c b/test/integration/no_std/rustc_std_internal_symbol_mangling/main.c new file mode 100644 index 0000000000..5c2b8177d1 --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/main.c @@ -0,0 +1,9 @@ +#include +#include + +extern int32_t return_5_in_no_std(); + +int main(int argc, char** argv) { + assert(return_5_in_no_std() == 5); + return 0; +} diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/main.rs b/test/integration/no_std/rustc_std_internal_symbol_mangling/main.rs new file mode 100644 index 0000000000..6d833eb49a --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/main.rs @@ -0,0 +1,38 @@ +#![no_std] +#![no_main] +#![feature(lang_items)] + +use core::arch::asm; +use core::arch::global_asm; +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + exit(1); +} + +global_asm! { + ".global _start", + "_start:", + "mov rdi, rsp", + "call start_main" +} + +fn exit(status: i32) -> ! { + unsafe { + asm!( + "syscall", + in("rax") 60, + in("rdi") status, + options(noreturn) + ); + } +} + +#[no_mangle] +unsafe fn start_main(_stack_top: *const u8) -> ! { + exit(0); +} + +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/no_std.rs b/test/integration/no_std/rustc_std_internal_symbol_mangling/no_std.rs new file mode 100644 index 0000000000..80e3568090 --- /dev/null +++ b/test/integration/no_std/rustc_std_internal_symbol_mangling/no_std.rs @@ -0,0 +1,16 @@ +use core::intrinsics; +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + intrinsics::abort() +} + +#[alloc_error_handler] +#[allow(clippy::panic)] +fn default_handler(layout: core::alloc::Layout) -> ! { + panic!("memory allocation of {} bytes failed", layout.size()) +} + +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} From 9e2c701e021da969379a8fba12abc6acf563f001 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Mon, 28 Apr 2025 16:48:41 +0000 Subject: [PATCH 11/19] mv no_std tests to top-level --- .../.bazelrc | 0 .../.gitignore | 0 .../BUILD.bazel | 0 .../MODULE.bazel | 2 +- .../WORKSPACE.bazel | 0 .../alloc.rs | 0 .../lib.rs | 0 .../main.c | 0 .../main.rs | 0 .../no_std.rs | 0 10 files changed, 1 insertion(+), 1 deletion(-) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/.bazelrc (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/.gitignore (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/BUILD.bazel (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/MODULE.bazel (97%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/WORKSPACE.bazel (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/alloc.rs (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/lib.rs (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/main.c (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/main.rs (100%) rename test/integration/{no_std/rustc_std_internal_symbol_mangling => no_std_rustc_std_internal_symbol_mangling}/no_std.rs (100%) diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/.bazelrc b/test/integration/no_std_rustc_std_internal_symbol_mangling/.bazelrc similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/.bazelrc rename to test/integration/no_std_rustc_std_internal_symbol_mangling/.bazelrc diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/.gitignore b/test/integration/no_std_rustc_std_internal_symbol_mangling/.gitignore similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/.gitignore rename to test/integration/no_std_rustc_std_internal_symbol_mangling/.gitignore diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/no_std_rustc_std_internal_symbol_mangling/BUILD.bazel similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/BUILD.bazel rename to test/integration/no_std_rustc_std_internal_symbol_mangling/BUILD.bazel diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/MODULE.bazel b/test/integration/no_std_rustc_std_internal_symbol_mangling/MODULE.bazel similarity index 97% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/MODULE.bazel rename to test/integration/no_std_rustc_std_internal_symbol_mangling/MODULE.bazel index 444136f22d..fbe6247895 100644 --- a/test/integration/no_std/rustc_std_internal_symbol_mangling/MODULE.bazel +++ b/test/integration/no_std_rustc_std_internal_symbol_mangling/MODULE.bazel @@ -6,7 +6,7 @@ module( bazel_dep(name = "rules_rust", version = "0.0.0") local_path_override( module_name = "rules_rust", - path = "../../../..", + path = "../../..", ) bazel_dep(name = "rules_cc", version = "0.1.1") diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/WORKSPACE.bazel b/test/integration/no_std_rustc_std_internal_symbol_mangling/WORKSPACE.bazel similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/WORKSPACE.bazel rename to test/integration/no_std_rustc_std_internal_symbol_mangling/WORKSPACE.bazel diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/alloc.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/alloc.rs similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/alloc.rs rename to test/integration/no_std_rustc_std_internal_symbol_mangling/alloc.rs diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/lib.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/lib.rs similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/lib.rs rename to test/integration/no_std_rustc_std_internal_symbol_mangling/lib.rs diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/main.c b/test/integration/no_std_rustc_std_internal_symbol_mangling/main.c similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/main.c rename to test/integration/no_std_rustc_std_internal_symbol_mangling/main.c diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/main.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/main.rs similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/main.rs rename to test/integration/no_std_rustc_std_internal_symbol_mangling/main.rs diff --git a/test/integration/no_std/rustc_std_internal_symbol_mangling/no_std.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/no_std.rs similarity index 100% rename from test/integration/no_std/rustc_std_internal_symbol_mangling/no_std.rs rename to test/integration/no_std_rustc_std_internal_symbol_mangling/no_std.rs From 78d8446706333801dd97092f67431e18aa08d64f Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 29 Apr 2025 19:28:02 +0000 Subject: [PATCH 12/19] merge new and old no_std tests --- .bazelci/presubmit.yml | 12 +++ rust/extensions.bzl | 8 ++ rust/repositories.bzl | 8 +- rust/settings/settings.bzl | 9 +- test/integration/no_std/.bazelrc | 4 + test/integration/no_std/MODULE.bazel | 25 +++++ .../.bazelrc | 93 ------------------- .../.gitignore | 2 - .../BUILD.bazel | 47 ---------- .../MODULE.bazel | 46 --------- .../WORKSPACE.bazel | 1 - .../alloc.rs | 6 -- .../lib.rs | 22 ----- .../main.c | 9 -- .../main.rs | 38 -------- .../no_std.rs | 16 ---- 16 files changed, 62 insertions(+), 284 deletions(-) delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/.bazelrc delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/.gitignore delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/BUILD.bazel delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/MODULE.bazel delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/WORKSPACE.bazel delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/alloc.rs delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/lib.rs delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/main.c delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/main.rs delete mode 100644 test/integration/no_std_rustc_std_internal_symbol_mangling/no_std.rs diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 7a931a2687..4c7bc8ed53 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -562,6 +562,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/rust/extensions.bzl b/rust/extensions.bzl index b89f79898c..7be9c09a81 100644 --- a/rust/extensions.bzl +++ b/rust/extensions.bzl @@ -61,6 +61,7 @@ def _rust_impl(module_ctx): "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]}, + "target_settings": [str(v) for v in repository_set.target_settings], "name": repository_set.name, "rustfmt_version": repository_set.rustfmt_version, "sha256s": repository_set.sha256s, @@ -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/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/settings.bzl b/rust/settings/settings.bzl index 355d526112..01efb47e64 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -128,7 +128,7 @@ def experimental_use_global_allocator(): def experimental_use_allocator_libraries_with_mangled_symbols(name): """A flag used to select allocator libraries implemented in rust that are compatible with rustc's symbol mangling. - Also a corresponding config setting that can be used in selects(). + Also corresponding on/off config settings. This currently requires nightly rustc from 2025-04-05 or later. """ @@ -144,6 +144,13 @@ def experimental_use_allocator_libraries_with_mangled_symbols(name): }, ) + 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/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/test/integration/no_std_rustc_std_internal_symbol_mangling/.bazelrc b/test/integration/no_std_rustc_std_internal_symbol_mangling/.bazelrc deleted file mode 100644 index 887352ed0f..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/.bazelrc +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -## Bazel Configuration Flags -## -## `.bazelrc` is a Bazel configuration file. -## https://bazel.build/docs/best-practices#bazelrc-file -############################################################################### - -# Build with no_std + alloc using cc_common.link infrastructure for linking -build:no_std_alloc_using_cc_common_link --@rules_rust//rust/toolchain/channel=nightly -build:no_std_alloc_using_cc_common_link --@rules_rust//rust/settings:experimental_use_cc_common_link=True -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 --@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 - -############################################################################### - -# https://bazel.build/reference/command-line-reference#flag--enable_platform_specific_config -common --enable_platform_specific_config - -# Enable the only currently supported report type -# https://bazel.build/reference/command-line-reference#flag--combined_report -coverage --combined_report=lcov - -# Avoid fully cached builds reporting no coverage and failing CI -# https://bazel.build/reference/command-line-reference#flag--experimental_fetch_all_coverage_outputs -coverage --experimental_fetch_all_coverage_outputs - -# Required for some of the tests -# https://bazel.build/reference/command-line-reference#flag--experimental_cc_shared_library -common --experimental_cc_shared_library - -############################################################################### -## Unique configuration groups -############################################################################### - -# Enable use of the nightly toolchains. -build:nightly --@rules_rust//rust/toolchain/channel=nightly - -# Enable rustfmt for all targets in the workspace -build:rustfmt --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect -build:rustfmt --output_groups=+rustfmt_checks - -# Enable clippy for all targets in the workspace -build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect -build:clippy --output_groups=+clippy_checks - -# Enable unpretty for all targets in the workspace -build:unpretty --aspects=@rules_rust//rust:defs.bzl%rust_unpretty_aspect -build:unpretty --output_groups=+rust_unpretty - -# `unpretty` requires the nightly toolchain. See tracking issue: -# https://github.com/rust-lang/rust/issues/43364 -build:unpretty --config=nightly - -############################################################################### -## Incompatibility flags -############################################################################### - -# https://github.com/bazelbuild/bazel/issues/8195 -build --incompatible_disallow_empty_glob=true - -# https://github.com/bazelbuild/bazel/issues/12821 -build --nolegacy_external_runfiles - -# Required for cargo_build_script support before Bazel 7 -build --incompatible_merge_fixed_and_default_shell_env - -# https://github.com/bazelbuild/bazel/issues/23043. -build --incompatible_autoload_externally= - -############################################################################### -## Bzlmod -############################################################################### - -# A configuration for disabling bzlmod. -common:no-bzlmod --noenable_bzlmod --enable_workspace - -# Disable the bzlmod lockfile, so we don't accidentally commit MODULE.bazel.lock -common --lockfile_mode=off - -############################################################################### -## Custom user flags -## -## This should always be the last thing in the `.bazelrc` file to ensure -## consistent behavior when setting flags in that file as `.bazelrc` files are -## evaluated top to bottom. -############################################################################### - -try-import %workspace%/user.bazelrc diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/.gitignore b/test/integration/no_std_rustc_std_internal_symbol_mangling/.gitignore deleted file mode 100644 index 2f0f755d60..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bazel-* -/MODULE.bazel.lock diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/no_std_rustc_std_internal_symbol_mangling/BUILD.bazel deleted file mode 100644 index cc90de45ec..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/BUILD.bazel +++ /dev/null @@ -1,47 +0,0 @@ -load("@no_std_crate_index//:defs.bzl", "aliases", "all_crate_deps") -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") -load( - "@rules_rust//rust:defs.bzl", - "rust_binary", - "rust_library", - "rust_shared_library", -) - -rust_shared_library( - name = "lib", - srcs = [ - "lib.rs", - "no_std.rs", - ], - crate_features = select({ - "@rules_rust//rust/settings:is_no_std": [], - "//conditions:default": ["std"], - }), - edition = "2021", - deps = ["custom_alloc"], -) - -rust_library( - name = "custom_alloc", - srcs = ["alloc.rs"], - aliases = aliases(), - deps = all_crate_deps(normal = True), -) - -cc_library( - name = "nostartfiles", - linkopts = ["-nostartfiles"], -) - -rust_binary( - name = "main", - srcs = ["main.rs"], - aliases = aliases(), - deps = all_crate_deps(normal = True) + [":nostartfiles"], -) - -cc_test( - name = "no_std_cc_test", - srcs = ["main.c"], - deps = [":lib"], -) diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/MODULE.bazel b/test/integration/no_std_rustc_std_internal_symbol_mangling/MODULE.bazel deleted file mode 100644 index fbe6247895..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/MODULE.bazel +++ /dev/null @@ -1,46 +0,0 @@ -module( - name = "rules_rust_test_no_std_rustc_std_internal_symbol_mangling", - version = "0.0.0", -) - -bazel_dep(name = "rules_rust", version = "0.0.0") -local_path_override( - module_name = "rules_rust", - path = "../../..", -) - -bazel_dep(name = "rules_cc", version = "0.1.1") -bazel_dep(name = "bazel_skylib", version = "1.7.1") -bazel_dep(name = "platforms", version = "0.0.11") - -rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") - -# A recent enough version of rustc that mangles the internal allocator symbols. -VERSION = "nightly/2025-04-08" - -rust.toolchain( - versions = [VERSION], -) -rust.repository_set( - name = "rust_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_triple = "x86_64-unknown-linux-gnu", - versions = [VERSION], -) -use_repo(rust, "rust_toolchains") - -register_toolchains("@rust_toolchains//:all") - -crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate") -crate.spec( - package = "libc_alloc", - version = "1.0.3", -) -crate.from_specs(name = "no_std_crate_index") -use_repo(crate, "no_std_crate_index") diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/WORKSPACE.bazel b/test/integration/no_std_rustc_std_internal_symbol_mangling/WORKSPACE.bazel deleted file mode 100644 index 0a53422387..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/WORKSPACE.bazel +++ /dev/null @@ -1 +0,0 @@ -workspace(name = "rules_rust_test_no_std_rustc_std_internal_symbol_mangling") diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/alloc.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/alloc.rs deleted file mode 100644 index 3cead000a3..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/alloc.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![no_std] - -use libc_alloc::LibcAlloc; - -#[global_allocator] -static ALLOCATOR: LibcAlloc = LibcAlloc; diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/lib.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/lib.rs deleted file mode 100644 index 03647155f7..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![no_std] -// These features are needed to support no_std + alloc -#![feature(lang_items)] -#![feature(alloc_error_handler)] -#![feature(core_intrinsics)] -#![allow(unused_imports)] -use custom_alloc; - -#[cfg(all(not(feature = "std"), not(test)))] -mod no_std; - -#[cfg(not(feature = "std"))] -#[no_mangle] -pub extern "C" fn return_5_in_no_std() -> i32 { - 5 -} - -#[cfg(feature = "std")] -#[no_mangle] -pub extern "C" fn return_5_in_no_std() -> i32 { - 6 -} diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/main.c b/test/integration/no_std_rustc_std_internal_symbol_mangling/main.c deleted file mode 100644 index 5c2b8177d1..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/main.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -extern int32_t return_5_in_no_std(); - -int main(int argc, char** argv) { - assert(return_5_in_no_std() == 5); - return 0; -} diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/main.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/main.rs deleted file mode 100644 index 6d833eb49a..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/main.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![no_std] -#![no_main] -#![feature(lang_items)] - -use core::arch::asm; -use core::arch::global_asm; -use core::panic::PanicInfo; - -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - exit(1); -} - -global_asm! { - ".global _start", - "_start:", - "mov rdi, rsp", - "call start_main" -} - -fn exit(status: i32) -> ! { - unsafe { - asm!( - "syscall", - in("rax") 60, - in("rdi") status, - options(noreturn) - ); - } -} - -#[no_mangle] -unsafe fn start_main(_stack_top: *const u8) -> ! { - exit(0); -} - -#[lang = "eh_personality"] -extern "C" fn eh_personality() {} diff --git a/test/integration/no_std_rustc_std_internal_symbol_mangling/no_std.rs b/test/integration/no_std_rustc_std_internal_symbol_mangling/no_std.rs deleted file mode 100644 index 80e3568090..0000000000 --- a/test/integration/no_std_rustc_std_internal_symbol_mangling/no_std.rs +++ /dev/null @@ -1,16 +0,0 @@ -use core::intrinsics; -use core::panic::PanicInfo; - -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - intrinsics::abort() -} - -#[alloc_error_handler] -#[allow(clippy::panic)] -fn default_handler(layout: core::alloc::Layout) -> ! { - panic!("memory allocation of {} bytes failed", layout.size()) -} - -#[lang = "eh_personality"] -extern "C" fn eh_personality() {} From 705bdfce95f259916269279d9396fd4cf6cf78bb Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 29 Apr 2025 19:40:28 +0000 Subject: [PATCH 13/19] unify cc_common_link tests --- .bazelci/presubmit.yml | 12 +++++ rust/extensions.bzl | 2 +- test/integration/cc_common_link/.bazelrc | 1 + test/integration/cc_common_link/MODULE.bazel | 24 ++++++++++ .../.bazelrc | 42 ---------------- .../.gitignore | 2 - .../BUILD.bazel | 25 ---------- .../MODULE.bazel | 48 ------------------- .../WORKSPACE.bazel | 1 - .../rustc_std_internal_symbol_mangling/dep.rs | 13 ----- .../test.cc | 10 ---- .../test.rs | 4 -- 12 files changed, 38 insertions(+), 146 deletions(-) delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.bazelrc delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc delete mode 100644 test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 4c7bc8ed53..8b1f02bfd6 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 diff --git a/rust/extensions.bzl b/rust/extensions.bzl index 7be9c09a81..99868b0dfe 100644 --- a/rust/extensions.bzl +++ b/rust/extensions.bzl @@ -61,10 +61,10 @@ def _rust_impl(module_ctx): "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]}, - "target_settings": [str(v) for v in repository_set.target_settings], "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, } 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/rustc_std_internal_symbol_mangling/.bazelrc b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.bazelrc deleted file mode 100644 index 44bf1ed56c..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.bazelrc +++ /dev/null @@ -1,42 +0,0 @@ -############################################################################### -## Bazel Configuration Flags -############################################################################### - -build --@rules_rust//rust/settings:experimental_use_cc_common_link=True -build --@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols=True - -############################################################################### - -# Enable rustfmt for all targets in the workspace -build:rustfmt --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect -build:rustfmt --output_groups=+rustfmt_checks - -# Enable clippy for all targets in the workspace -build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect -build:clippy --output_groups=+clippy_checks - -############################################################################### -## Incompatibility flags -############################################################################### - -# https://github.com/bazelbuild/bazel/issues/8195 -build --incompatible_disallow_empty_glob=true - -# https://github.com/bazelbuild/bazel/issues/12821 -build --nolegacy_external_runfiles - -# Required for cargo_build_script support before Bazel 7 -build --incompatible_merge_fixed_and_default_shell_env - -# https://github.com/bazelbuild/bazel/issues/23043. -build --incompatible_autoload_externally= - -############################################################################### -## Bzlmod -############################################################################### - -# A configuration for disabling bzlmod. -common:no-bzlmod --noenable_bzlmod --enable_workspace - -# Disable the bzlmod lockfile, so we don't accidentally commit MODULE.bazel.lock -common --lockfile_mode=off diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore deleted file mode 100644 index 2f0f755d60..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bazel-* -/MODULE.bazel.lock diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel deleted file mode 100644 index 6bcad908eb..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/BUILD.bazel +++ /dev/null @@ -1,25 +0,0 @@ -load("@rules_cc//cc:defs.bzl", "cc_test") -load( - "@rules_rust//rust:defs.bzl", - "rust_library", - "rust_test", -) - -rust_library( - name = "rsdep", - srcs = ["dep.rs"], -) - -rust_test( - name = "rstest", - srcs = ["test.rs"], - deps = [ - ":rsdep", - ], -) - -cc_test( - name = "cctest", - srcs = ["test.cc"], - deps = [":rsdep"], -) diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel deleted file mode 100644 index f019e43a62..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/MODULE.bazel +++ /dev/null @@ -1,48 +0,0 @@ -# Repository setup to validate rules_rust with rustc that mangles rustc_std_internal_symbols. -# -# To support linking rust code into non-rust contexts, we must provide -# implementations of the default internal rust allocator symbols, e.g.: -# https://github.com/bazelbuild/rules_rust/blob/main/ffi/cc/allocator_library/allocator_library.cc -# -# Recent versions of rustc started to mangle these internal symbols, -# rendering our c++ implementations ineffective: -# https://github.com/rust-lang/rust/pull/127173 -module( - name = "rules_rust_test_cc_common_link_rustc_std_internal_symbol_mangling", - version = "0.0.0", -) - -bazel_dep(name = "rules_rust", version = "0.0.0") -local_path_override( - module_name = "rules_rust", - path = "../../../..", -) - -bazel_dep(name = "rules_cc", version = "0.1.1") -bazel_dep(name = "bazel_skylib", version = "1.7.1") -bazel_dep(name = "platforms", version = "0.0.11") - -rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") - -# A recent enough version of rustc that mangles the internal allocator symbols. -VERSION = "nightly/2025-04-08" - -rust.toolchain( - versions = [VERSION], -) -rust.repository_set( - name = "rust_linux_x86_64", - allocator_library = "@rules_rust//ffi/rs:empty", - edition = "2021", - exec_triple = "x86_64-unknown-linux-gnu", - #global_allocator_library = "", - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], - target_triple = "x86_64-unknown-linux-gnu", - versions = [VERSION], -) -use_repo(rust, "rust_toolchains") - -register_toolchains("@rust_toolchains//:all") diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel deleted file mode 100644 index c29b7e548f..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/WORKSPACE.bazel +++ /dev/null @@ -1 +0,0 @@ -workspace(name = "rules_rust_test_cc_common_link_rustc_std_internal_symbol_mangling") diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs deleted file mode 100644 index c690c08b14..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/dep.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[no_mangle] -pub extern "C" fn rdep() -> i32 { - // Just some logic complicated enough to require heap - // allocations. - use std::convert::TryInto; - let mut v = vec![1, 2, 3]; - while v.len() < 1000 { - let n = v.len(); - v.push(v[n-1] + v[n-2]); - v.push(v[n-3]); - } - return v.len().try_into().unwrap(); // returns 1001 -} diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc deleted file mode 100644 index ce13d7801d..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include - -extern "C" int rdep(); - -int main() { - if (rdep() != 1001) { - return 1; - } - return 0; -} diff --git a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs b/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs deleted file mode 100644 index 7f433b89f7..0000000000 --- a/test/integration/cc_common_link/rustc_std_internal_symbol_mangling/test.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[test] -fn test() { - assert_eq!(1001, rsdep::rdep()); -} From 78c46cda92b438eca7a683e93b9d389984953cd8 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 29 Apr 2025 19:47:26 +0000 Subject: [PATCH 14/19] unify cc_common_link_with_global_alloc tests --- .bazelci/presubmit.yml | 12 +++++ .../cc_common_link_with_global_alloc/.bazelrc | 1 + .../MODULE.bazel | 24 ++++++++++ .../.bazelrc | 43 ----------------- .../.gitignore | 2 - .../BUILD.bazel | 17 ------- .../MODULE.bazel | 37 --------------- .../WORKSPACE.bazel | 1 - .../main.rs | 46 ------------------- 9 files changed, 37 insertions(+), 146 deletions(-) delete mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc delete mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore delete mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel delete mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel delete mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel delete mode 100644 test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 8b1f02bfd6..b5b5d71752 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -562,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 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/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc deleted file mode 100644 index a09e927526..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.bazelrc +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################### -## Bazel Configuration Flags -############################################################################### - -build --@rules_rust//rust/settings:experimental_use_cc_common_link=True -build --@rules_rust//rust/settings:experimental_use_global_allocator=True -build --@rules_rust//rust/settings:experimental_use_allocator_libraries_with_mangled_symbols=True - -############################################################################### - -# Enable rustfmt for all targets in the workspace -build:rustfmt --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect -build:rustfmt --output_groups=+rustfmt_checks - -# Enable clippy for all targets in the workspace -build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect -build:clippy --output_groups=+clippy_checks - -############################################################################### -## Incompatibility flags -############################################################################### - -# https://github.com/bazelbuild/bazel/issues/8195 -build --incompatible_disallow_empty_glob=true - -# https://github.com/bazelbuild/bazel/issues/12821 -build --nolegacy_external_runfiles - -# Required for cargo_build_script support before Bazel 7 -build --incompatible_merge_fixed_and_default_shell_env - -# https://github.com/bazelbuild/bazel/issues/23043. -build --incompatible_autoload_externally= - -############################################################################### -## Bzlmod -############################################################################### - -# A configuration for disabling bzlmod. -common:no-bzlmod --noenable_bzlmod --enable_workspace - -# Disable the bzlmod lockfile, so we don't accidentally commit MODULE.bazel.lock -common --lockfile_mode=off diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore deleted file mode 100644 index 2f0f755d60..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bazel-* -/MODULE.bazel.lock diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel deleted file mode 100644 index d037a22e52..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/BUILD.bazel +++ /dev/null @@ -1,17 +0,0 @@ -load( - "@rules_rust//rust:defs.bzl", - "rust_binary", - "rust_test", -) - -rust_binary( - name = "main", - srcs = ["main.rs"], - edition = "2021", -) - -rust_test( - name = "global_alloc_test", - crate = ":main", - edition = "2021", -) diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel deleted file mode 100644 index 330e590007..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/MODULE.bazel +++ /dev/null @@ -1,37 +0,0 @@ -module( - name = "rules_rust_test_cc_common_link_with_global_alloc_rustc_std_internal_symbol_mangling", - version = "0.0.0", -) - -bazel_dep(name = "rules_rust", version = "0.0.0") -local_path_override( - module_name = "rules_rust", - path = "../../../..", -) - -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") - -# A recent enough version of rustc that mangles the internal allocator symbols. -VERSION = "nightly/2025-04-08" - -rust.toolchain( - versions = [VERSION], -) -rust.repository_set( - name = "rust_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_triple = "x86_64-unknown-linux-gnu", - versions = [VERSION], -) -use_repo(rust, "rust_toolchains") - -register_toolchains("@rust_toolchains//:all") diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel deleted file mode 100644 index 571df760ab..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/WORKSPACE.bazel +++ /dev/null @@ -1 +0,0 @@ -workspace(name = "rules_rust_test_cc_common_link_with_global_alloc_rustc_std_internal_symbol_mangling") diff --git a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs b/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs deleted file mode 100644 index 79dccff40f..0000000000 --- a/test/integration/cc_common_link_with_global_alloc/rustc_std_internal_symbol_mangling/main.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::alloc::{GlobalAlloc, Layout, System}; -use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; - -static ALLOCATED: AtomicUsize = AtomicUsize::new(0); - -struct MyAllocator; - -unsafe impl GlobalAlloc for MyAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let ret = System.alloc(layout); - if !ret.is_null() { - ALLOCATED.fetch_add(layout.size(), SeqCst); - } - ret - } - - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - System.dealloc(ptr, layout); - ALLOCATED.fetch_sub(layout.size(), SeqCst); - } -} - -#[global_allocator] -static GLOBAL: MyAllocator = MyAllocator; - -fn main() { - println!("allocated bytes before main: {}", ALLOCATED.load(SeqCst)); -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_global_alloc_was_used() { - // Allocated bytes before main - let bytes_start = ALLOCATED.load(SeqCst); - - let _x = Box::new(5); // 4 bytes - let _y = Box::new(true); // 1 byte - - let bytes_end = ALLOCATED.load(SeqCst); - - assert_eq!(bytes_end - bytes_start, 5); - } -} From a9914a4e63f98f288a5a45050f6fe7f77f1e5c45 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 29 Apr 2025 20:24:34 +0000 Subject: [PATCH 15/19] try to pass the alloc lib expliticly --- .bazelci/presubmit.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index b5b5d71752..109c0c8cfe 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -543,9 +543,9 @@ tasks: test_targets: - "//..." build_flags: - - "--config=mangled_alloc_symbols" + - "--config=mangled_alloc_symbols --linkopt=bazel-out/k8-fastbuild/bin/external/rules_rust+/ffi/rs/allocator_library/liballocator_library-256964584.a" test_flags: - - "--config=mangled_alloc_symbols" + - "--config=mangled_alloc_symbols --linkopt=bazel-out/k8-fastbuild/bin/external/rules_rust+/ffi/rs/allocator_library/liballocator_library-256964584.a" cc_common_link_with_global_alloc_ubuntu2004: name: Build via cc_common.link using a global allocator platform: ubuntu2004 From f5b87b01375c3e59e817eacdfefe3b1298737e6e Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 29 Apr 2025 20:27:14 +0000 Subject: [PATCH 16/19] ditto --- .bazelci/presubmit.yml | 4 ++-- test/integration/cc_common_link/.bazelrc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 109c0c8cfe..b5b5d71752 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -543,9 +543,9 @@ tasks: test_targets: - "//..." build_flags: - - "--config=mangled_alloc_symbols --linkopt=bazel-out/k8-fastbuild/bin/external/rules_rust+/ffi/rs/allocator_library/liballocator_library-256964584.a" + - "--config=mangled_alloc_symbols" test_flags: - - "--config=mangled_alloc_symbols --linkopt=bazel-out/k8-fastbuild/bin/external/rules_rust+/ffi/rs/allocator_library/liballocator_library-256964584.a" + - "--config=mangled_alloc_symbols" cc_common_link_with_global_alloc_ubuntu2004: name: Build via cc_common.link using a global allocator platform: ubuntu2004 diff --git a/test/integration/cc_common_link/.bazelrc b/test/integration/cc_common_link/.bazelrc index 5a87dbae73..8cd41bb9d4 100644 --- a/test/integration/cc_common_link/.bazelrc +++ b/test/integration/cc_common_link/.bazelrc @@ -4,6 +4,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 +build:mangled_alloc_symbols --linkopt=bazel-out/k8-fastbuild/bin/external/rules_rust+/ffi/rs/allocator_library/liballocator_library-256964584.a ############################################################################### From b3a613bad6720496527089cd68be5316df35685a Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 6 May 2025 13:50:25 +0000 Subject: [PATCH 17/19] put the alloc libs at the bottom of stdlibs --- rust/private/providers.bzl | 3 ++ rust/private/rust.bzl | 10 ++++ rust/private/rustc.bzl | 15 +++--- rust/toolchain.bzl | 68 ++++++++++++++---------- test/integration/cc_common_link/.bazelrc | 1 - 5 files changed, 62 insertions(+), 35 deletions(-) diff --git a/rust/private/providers.bzl b/rust/private/providers.bzl index 0ce4069ade..82868c7152 100644 --- a/rust/private/providers.bzl +++ b/rust/private/providers.bzl @@ -194,5 +194,8 @@ AllocatorLibrariesInfo = provider( 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", }, ) diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 86bd23d867..3d21574f04 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -1587,12 +1587,18 @@ rust_library_group = rule( ) def _rust_allocator_libraries_impl(ctx): + toolchain = find_toolchain(ctx) allocator_library = ctx.attr.allocator_library[CcInfo] if ctx.attr.allocator_library else None global_allocator_library = ctx.attr.global_allocator_library[CcInfo] if ctx.attr.global_allocator_library else None + make_ccinfo = lambda lib, std: toolchain.make_libstd_and_allocator_ccinfo(ctx.label, ctx.actions, lib, 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 @@ -1610,6 +1616,10 @@ rust_allocator_libraries = rule( providers = [CcInfo], ), }, + toolchains = [ + str(Label("//rust:toolchain_type")), + "@bazel_tools//tools/cpp:toolchain_type", + ], ) def _replace_illlegal_chars(name): diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 6867fd8d68..6778ad3f81 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1633,23 +1633,26 @@ def _get_std_and_alloc_info(ctx, toolchain, crate_info): attr_allocator_library = None attr_global_allocator_library = None if _should_use_rustc_allocator_libraries(toolchain) and hasattr(ctx.attr, "allocator_libraries"): - attr_allocator_library = ctx.attr.allocator_libraries[AllocatorLibrariesInfo].allocator_library - attr_global_allocator_library = ctx.attr.allocator_libraries[AllocatorLibrariesInfo].global_allocator_library + libs = ctx.attr.allocator_libraries[AllocatorLibrariesInfo] + return libs.libstd_and_allocator_ccinfo + attr_allocator_library = libs.allocator_library + attr_global_allocator_library = libs.global_allocator_library if is_exec_configuration(ctx): if attr_allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_allocator_library, toolchain.libstd_no_allocator_ccinfo) + 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): if attr_global_allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_global_allocator_library, toolchain.nostd_no_allocator_ccinfo) + return libs.nostd_and_global_allocator_ccinfo return toolchain.nostd_and_global_allocator_ccinfo else: if attr_global_allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_global_allocator_library, toolchain.libstd_no_allocator_ccinfo) + return libs.libstd_and_global_allocator_ccinfo return toolchain.libstd_and_global_allocator_ccinfo if attr_allocator_library: - return _merge_attr_and_toolchain_alloc_info(attr_allocator_library, toolchain.libstd_no_allocator_ccinfo) + print("ret: ", attr_allocator_library) + return libs.libstd_and_allocator_ccinfo return toolchain.libstd_and_allocator_ccinfo def _is_dylib(dep): diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index eb7c585658..b3e2964a59 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -124,7 +124,7 @@ 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: @@ -137,14 +137,14 @@ 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: @@ -158,7 +158,6 @@ 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 rust_common.stdlib_info in rust_std: @@ -167,7 +166,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 +175,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 +187,27 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s )) if rust_stdlib_info.std_rlibs: + allocator_library_inputs = [] + if allocator_library and allocator_library.linking_context.linker_inputs: + allocator_library_inputs = [depset( + [ + l + for inp in allocator_library.linking_context.linker_inputs.to_list() + for l in inp.libraries + ], + )] 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 +230,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 +240,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 +249,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 +257,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 +277,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 +286,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], @@ -296,15 +306,10 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s else: 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] - cc_infos.append(CcInfo( linking_context = cc_common.create_linking_context( linker_inputs = depset( [link_inputs], - transitive = allocator_inputs, order = "topological", ), ), @@ -657,6 +662,12 @@ 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, allocator_library, std) toolchain = platform_common.ToolchainInfo( all_files = sysroot.all_files, @@ -669,11 +680,12 @@ 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_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, ctx.attr.global_allocator_library, "no_std_with_alloc"), - libstd_no_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, None, "std"), - nostd_no_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, rust_std, None, "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, + libstd_no_allocator_ccinfo = make_local_ccinfo(None, "std"), + nostd_no_allocator_ccinfo = make_local_ccinfo(None, "no_std_with_alloc"), llvm_cov = ctx.file.llvm_cov, llvm_profdata = ctx.file.llvm_profdata, lto = lto, diff --git a/test/integration/cc_common_link/.bazelrc b/test/integration/cc_common_link/.bazelrc index 8cd41bb9d4..5a87dbae73 100644 --- a/test/integration/cc_common_link/.bazelrc +++ b/test/integration/cc_common_link/.bazelrc @@ -4,7 +4,6 @@ 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 -build:mangled_alloc_symbols --linkopt=bazel-out/k8-fastbuild/bin/external/rules_rust+/ffi/rs/allocator_library/liballocator_library-256964584.a ############################################################################### From 2dad83230da8de131bfb9d59b26a39d803df3428 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 6 May 2025 22:39:22 +0000 Subject: [PATCH 18/19] adapt allocator libs to be deps of liballoc --- rust/private/rustc.bzl | 7 ------- rust/toolchain.bzl | 24 +++++++++++++++--------- test/unit/cc_info/cc_info_test.bzl | 3 +++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 6778ad3f81..aefdb1800e 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1604,11 +1604,6 @@ def _is_no_std(ctx, toolchain, crate_info): return False return True -def _merge_attr_and_toolchain_alloc_info(attr_alloc_cc_info, toolchain_alloc_cc_info): - if not attr_alloc_cc_info: - fail("empty attr_alloc_cc_info") - return cc_common.merge_cc_infos(cc_infos = [attr_alloc_cc_info, toolchain_alloc_cc_info]) - 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]: @@ -1634,7 +1629,6 @@ def _get_std_and_alloc_info(ctx, toolchain, crate_info): attr_global_allocator_library = None if _should_use_rustc_allocator_libraries(toolchain) and hasattr(ctx.attr, "allocator_libraries"): libs = ctx.attr.allocator_libraries[AllocatorLibrariesInfo] - return libs.libstd_and_allocator_ccinfo attr_allocator_library = libs.allocator_library attr_global_allocator_library = libs.global_allocator_library if is_exec_configuration(ctx): @@ -1651,7 +1645,6 @@ def _get_std_and_alloc_info(ctx, toolchain, crate_info): return libs.libstd_and_global_allocator_ccinfo return toolchain.libstd_and_global_allocator_ccinfo if attr_allocator_library: - print("ret: ", attr_allocator_library) return libs.libstd_and_allocator_ccinfo return toolchain.libstd_and_allocator_ccinfo diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index b3e2964a59..b7630379bf 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -188,14 +188,22 @@ def _make_libstd_and_allocator_ccinfo(cc_toolchain, feature_configuration, label if rust_stdlib_info.std_rlibs: allocator_library_inputs = [] + if allocator_library and allocator_library.linking_context.linker_inputs: - allocator_library_inputs = [depset( - [ - l - for inp in allocator_library.linking_context.linker_inputs.to_list() - for l in inp.libraries - ], - )] + # Repackage the allocator library linker inputs as transitive + # inputs to the liballoc from the standard library. + # The pattern `linker_inputs.to_list()[0]` extracts the first + # `LinkerInput` from the context, which contains the allocator + # library artifacts. Later linker inputs contain extra linker + # information that was created while building the allocator library + # itself; this is redundant as it will be re-established by this + # function. + # The `to_list()` of the linker_inputs depset is OK, as it only + # happens once per allocator-library target in the build graph (and + # we usually only have a few). + link_inp = allocator_library.linking_context.linker_inputs.to_list()[0] + allocator_library_inputs = [depset(link_inp.libraries)] + alloc_inputs = depset( [_ltl(f, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.alloc_files], transitive = allocator_library_inputs, @@ -684,8 +692,6 @@ def _rust_toolchain_impl(ctx): 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, - libstd_no_allocator_ccinfo = make_local_ccinfo(None, "std"), - nostd_no_allocator_ccinfo = make_local_ccinfo(None, "no_std_with_alloc"), llvm_cov = ctx.file.llvm_cov, llvm_profdata = ctx.file.llvm_profdata, lto = lto, diff --git a/test/unit/cc_info/cc_info_test.bzl b/test/unit/cc_info/cc_info_test.bzl index e4d004b126..12450c2d2c 100644 --- a/test/unit/cc_info/cc_info_test.bzl +++ b/test/unit/cc_info/cc_info_test.bzl @@ -12,6 +12,9 @@ def _assert_cc_info_has_library_to_link(env, tut, type, ccinfo_count): asserts.true(env, CcInfo in tut, "rust_library should provide CcInfo") cc_info = tut[CcInfo] linker_inputs = cc_info.linking_context.linker_inputs.to_list() + for li in linker_inputs: + print("li.o: ", li.owner) + print("li.l: ", li.libraries) asserts.equals(env, ccinfo_count, len(linker_inputs)) library_to_link = linker_inputs[0].libraries[0] asserts.equals(env, False, library_to_link.alwayslink) From 47505fd17a7833e2c4769757b81d5e72e734a0d6 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Thu, 8 May 2025 15:31:29 +0000 Subject: [PATCH 19/19] add an alloc impl provider --- rust/private/providers.bzl | 7 +++++++ rust/private/rust.bzl | 25 ++++++++++++++++------- rust/private/rustc.bzl | 12 ++++++++--- rust/toolchain.bzl | 41 +++++++++++++++++++++++--------------- 4 files changed, 59 insertions(+), 26 deletions(-) diff --git a/rust/private/providers.bzl b/rust/private/providers.bzl index 82868c7152..5c47bf14cb 100644 --- a/rust/private/providers.bzl +++ b/rust/private/providers.bzl @@ -199,3 +199,10 @@ AllocatorLibrariesInfo = provider( "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 3d21574f04..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", "AllocatorLibrariesInfo", "BuildInfo", "LintsInfo") +load( + "//rust/private:providers.bzl", + "AllocatorLibrariesImplInfo", + "AllocatorLibrariesInfo", + "BuildInfo", + "LintsInfo", +) load("//rust/private:rustc.bzl", "rustc_compile_action") load( "//rust/private:utils.bzl", @@ -1588,10 +1594,15 @@ rust_library_group = rule( def _rust_allocator_libraries_impl(ctx): toolchain = find_toolchain(ctx) - allocator_library = ctx.attr.allocator_library[CcInfo] if ctx.attr.allocator_library else None - global_allocator_library = ctx.attr.global_allocator_library[CcInfo] if ctx.attr.global_allocator_library else None - - make_ccinfo = lambda lib, std: toolchain.make_libstd_and_allocator_ccinfo(ctx.label, ctx.actions, lib, std) + 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, @@ -1609,11 +1620,11 @@ rust_allocator_libraries = rule( attrs = { "allocator_library": attr.label( doc = "An optional library to provide when a default rust allocator is used.", - providers = [CcInfo], + providers = [AllocatorLibrariesImplInfo], ), "global_allocator_library": attr.label( doc = "An optional library to provide when a default rust allocator is used.", - providers = [CcInfo], + providers = [AllocatorLibrariesImplInfo], ), }, toolchains = [ diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index aefdb1800e..9b6c824f4b 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", "AllocatorLibrariesInfo", "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( @@ -1713,7 +1713,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 @@ -1729,6 +1730,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, @@ -1802,7 +1805,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 += [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/toolchain.bzl b/rust/toolchain.bzl index b7630379bf..c912d8101d 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -9,6 +9,7 @@ load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//rust/platform:triple.bzl", "triple") load("//rust/private:common.bzl", "rust_common") load("//rust/private:lto.bzl", "RustLtoInfo") +load("//rust/private:providers.bzl", "AllocatorLibrariesImplInfo") load("//rust/private:rust_analyzer.bzl", _rust_analyzer_toolchain = "rust_analyzer_toolchain") load( "//rust/private:rustfmt.bzl", @@ -150,7 +151,10 @@ def _make_libstd_and_allocator_ccinfo(cc_toolchain, feature_configuration, label Args: ctx (ctx): The rule's context object. 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. @@ -159,6 +163,10 @@ def _make_libstd_and_allocator_ccinfo(cc_toolchain, feature_configuration, label A CcInfo object for the required libraries, or None if no such libraries are available. """ cc_infos = [] + if not type(allocator_library) == "struct": + fail("todo") + if not any([hasattr(allocator_library, field) for field in ["cc_info", "allocator_libraries_impl_info"]]): + fail("todo") if not rust_common.stdlib_info in rust_std: fail(dedent("""\ @@ -189,20 +197,11 @@ def _make_libstd_and_allocator_ccinfo(cc_toolchain, feature_configuration, label if rust_stdlib_info.std_rlibs: allocator_library_inputs = [] - if allocator_library and allocator_library.linking_context.linker_inputs: - # Repackage the allocator library linker inputs as transitive - # inputs to the liballoc from the standard library. - # The pattern `linker_inputs.to_list()[0]` extracts the first - # `LinkerInput` from the context, which contains the allocator - # library artifacts. Later linker inputs contain extra linker - # information that was created while building the allocator library - # itself; this is redundant as it will be re-established by this - # function. - # The `to_list()` of the linker_inputs depset is OK, as it only - # happens once per allocator-library target in the build graph (and - # we usually only have a few). - link_inp = allocator_library.linking_context.linker_inputs.to_list()[0] - allocator_library_inputs = [depset(link_inp.libraries)] + 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, actions, cc_toolchain, feature_configuration) for f in rust_stdlib_info.alloc_files], @@ -314,10 +313,15 @@ def _make_libstd_and_allocator_ccinfo(cc_toolchain, feature_configuration, label else: fail("Requested '{}' std mode is currently not supported.".format(std)) + allocator_inputs = None + 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( linker_inputs = depset( [link_inputs], + transitive = allocator_inputs, order = "topological", ), ), @@ -675,7 +679,12 @@ def _rust_toolchain_impl(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, 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,