You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposal attempts to provide a supported/official solution for the following requirements:
Linking is not done by rustc. (For example, Chromium uses clang tooling to link the final executable or dll binary. Such binary contains a mix of object files built by clang + ones built by rustc.)
A custom global allocator can be provided. (For example, Chromium uses PartitionAlloc.)
Status Quo
As discussed in rust-lang/rust#73632 there is currently no official support for linking rlibs using a non-Rust linker. An officially supported way to generate __rust_alloc is one missing piece of the puzzle here.
So far Chromium has been defining a weak__rust_alloc, __rust_no_alloc_shim_is_unstable (see rust-lang/rust#86844 by @bjorn3), etc. as a work around. This workaround stops working after rust-lang/rust#127173 which starts expecting __rust_alloc to be mangled.
#[global_allocator] and GlobalAllocator can be used to provide a custom memory allocator to Rust code. OTOH, IIUC #[global_allocator] only takes effect if the final linking is driven by rustc (and one of the requirements here is that linking is not done by rustc).
Proposal
The proposal here is to introduce a new -Zemit-code-for-final-artifact-to-link flag for rustc. When -Zemit-code-for-final-artifact-to-link flag is passed to rustc, then it will generate the same additional code as when linking the final binary: allocator-related definitions, maybe other definitions (e.g. for panic behavior). What exact code needs to be generated is a little ambiguous at this point - one way to clarify what this means is to require that this should generate sufficient definitions to ensure that linking by non-rustc will succeed.
The requirements can then be met by:
Defining a #[global_allocator] in global_allocator.rs (instead of defining __rust_alloc etc.)
Asking rustc to emit __rust_alloc / __rdl_alloc (or however these implementation details are named in the future) when building global_allocator.rlib - something like: rustc --crate-type=rlib ./global_allocator.rs -Zemit-code-for-final-artifact-to-link
Build other rlibs as usual (i.e. without-Zemit-code-for-final-artifact-to-link)
Using another linker (e.g. one that comes with clang) to link global_allocator.rlib and other rlibs into a final executable/binary.
Open questions
What should the new command-line flag be called? Does emit-code-for-final-artifact-to-link sound ok?
I assume that for now we still want to introduce a new -Z flag, because the proposal from Policy change around adding new unstable flags #787 hasn’t yet been adopted. OTOH, if needed we can spell the new option as -Zunstable-options -Cemit-code-for-final-artifact-to-link
Is it okay to ignore that GlobalAllocator doesn’t have an equivalent of __rust_alloc_error_handler?
Alternatives considered
Some people proposed--crate-type=allocator-shim. I think that it is preferable to keep --crate-type as a separate, independent knob, because -Z emit-code-for-final-artifact-to-link probably makes sense not only for --crate-type=rlib but also for --crate-type=staticlib. OTOH, -Z emit-code-for-final-artifact-to-link probably doesn’t make much sense for --crate-type=proc-macro and is already implied for --crate-type=bin (not sure about cdylib and dylib).
Figure out a workaround for Chromium that doesn’t require changes to rustc. AFAIK no such workaround has been identified so far, but let me list some ideas that have been considered:
Replicate the new mangling scheme in Chromium’s //build/rust/std/remap_alloc.cc - e.g. instead of naming the function __rust_alloc name it __rust_alloc_whatever_mangled_form_this_has. IIUC Rust’s mangling scheme includes a hash of the toolchain version + command-line options, and therefore this idea won’t work. I think.
A compiler team member or contributor who is knowledgeable in the area can second by writing @rustbot second.
Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a -C flag, then full team check-off is required.
Compiler team members can initiate a check-off via @rfcbot fcp merge on either the MCP or the PR.
Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.
Motivation / Requirements
This proposal attempts to provide a supported/official solution for the following requirements:
rustc. (For example, Chromium usesclangtooling to link the final executable or dll binary. Such binary contains a mix of object files built byclang+ ones built byrustc.)Status Quo
As discussed in rust-lang/rust#73632 there is currently no official support for linking rlibs using a non-Rust linker. An officially supported way to generate
__rust_allocis one missing piece of the puzzle here.So far Chromium has been defining a weak
__rust_alloc,__rust_no_alloc_shim_is_unstable(see rust-lang/rust#86844 by @bjorn3), etc. as a work around. This workaround stops working after rust-lang/rust#127173 which starts expecting__rust_allocto be mangled.There seems to be some support for adding a flag to
rustcto generate allocator *.a file to pass to the linker - see this comment by @alexcrichton or this comment by @hlopko.#[global_allocator]andGlobalAllocatorcan be used to provide a custom memory allocator to Rust code. OTOH, IIUC#[global_allocator]only takes effect if the final linking is driven byrustc(and one of the requirements here is that linking is not done byrustc).Proposal
The proposal here is to introduce a new
-Zemit-code-for-final-artifact-to-linkflag forrustc. When-Zemit-code-for-final-artifact-to-linkflag is passed torustc, then it will generate the same additional code as when linking the final binary: allocator-related definitions, maybe other definitions (e.g. for panic behavior). What exact code needs to be generated is a little ambiguous at this point - one way to clarify what this means is to require that this should generate sufficient definitions to ensure that linking by non-rustcwill succeed.The requirements can then be met by:
#[global_allocator]inglobal_allocator.rs(instead of defining__rust_allocetc.)rustcto emit__rust_alloc/__rdl_alloc(or however these implementation details are named in the future) when buildingglobal_allocator.rlib- something like:rustc --crate-type=rlib ./global_allocator.rs -Zemit-code-for-final-artifact-to-link-Zemit-code-for-final-artifact-to-link)clang) to linkglobal_allocator.rliband other rlibs into a final executable/binary.Open questions
emit-code-for-final-artifact-to-linksound ok?-Zflag, because the proposal from Policy change around adding new unstable flags #787 hasn’t yet been adopted. OTOH, if needed we can spell the new option as-Zunstable-options -Cemit-code-for-final-artifact-to-linkGlobalAllocatordoesn’t have an equivalent of__rust_alloc_error_handler?Alternatives considered
--crate-type=allocator-shim. I think that it is preferable to keep--crate-typeas a separate, independent knob, because-Z emit-code-for-final-artifact-to-linkprobably makes sense not only for--crate-type=rlibbut also for--crate-type=staticlib. OTOH,-Z emit-code-for-final-artifact-to-linkprobably doesn’t make much sense for--crate-type=proc-macroand is already implied for--crate-type=bin(not sure aboutcdylibanddylib).rustc. AFAIK no such workaround has been identified so far, but let me list some ideas that have been considered://build/rust/std/remap_alloc.cc- e.g. instead of naming the function__rust_allocname it__rust_alloc_whatever_mangled_form_this_has. IIUC Rust’s mangling scheme includes a hash of the toolchain version + command-line options, and therefore this idea won’t work. I think.Mentors or Reviewers
/cc @chbaker0, @alanzhao1, @zmodem from Chromium
Process
The main points of the Major Change Process are as follows:
@rustbot second.-C flag, then full team check-off is required.@rfcbot fcp mergeon either the MCP or the PR.You can read more about Major Change Proposals on forge.