Pre-RFC: Stabilize a version of the `rlib` format

That is basically equivalent to merging cargo into rustc as the standard library uses crates from crates.io (by the way many build systems don't allow network access) and some of which use build scripts.

I think there's been a bit of a misunderstanding—it's not a proposal to have rustc itself be responsible for building the standard library from source. That's the responsibility of the regular old Rust toolchain build system (x.py, etc.) Rather it's that rustc knows how to bundle a pre-built standard library together into a libstdrust.a. As I mentioned, this can already be done today by building a 0-byte lib.rs file with --crate-type=staticlib.

1 Like

I see. Makes sense.

Because archives do not deal with symbol visibility and #[used] properly.

If you again take a step back. You want to use ld for mixed C++ and Rust binaries. You don't want to have a prelink step of rustc before ld. Given the constraints what is the solution?

  • have rustc compile every crate into an object or archive file?
  • idk

My comment on the issue goes into (extensive, perhaps too much detail) detail about what the fundamental problem we want to solve is, and the constraints on the solution space (with useful commentary from various folks in the following comments).

1 Like

I prefer to solve problems in an abstract way before talking about the data layout. I guess you want something like a shared library per crate. It only contains the generated code of the crate and has dependencies on other crates/shared libraries.

Also a curious outsider here (and replying pretty late), but why would this be the case? The archive index doesn't have a notion of those, but the actual object files contained inside them will, and that's what should matter for linking. LLD 15 onwards ignores the archive index entirely (after ⚙ D119074 [ELF] Parse archives as --start-lib object files), and I believe mold does too.

The way Rust partition a single compilation unit (crate) into multiple CGUs means that we are currently exposing some symbols that shouldn't be exposed so they can be referenced from other CGUs. They are supposed to be crate-local symbols, but we make currently make them global symbols, because they can't be local symbols.

Someone is trying to use --emit obj in meson:

ELF's "hidden symbol" feature (localized within a shared object) could help here, and I think there is also a way to tell ld -r (partial link) to turn certain global symbols into local ones, but I can't find it in the manpage today.

That doesn't help for crate-local functions and statics used #[inline] functions as those can be inlined into an entirely different shared object while still needing to refer to the original versions of the functions and statics.

I'm not sure Windows supports this and on macOS it seems to be broken. I was using it in cg_clif in the inline assembly implementation and on macOS it only gives linker errors when using those partially linked object files due to missing symbols.

A new year has come, and with it a new version of this pre-RFC! It incorporates a lot of the feedback from previous revisions. In particular, it provides a standard way to link against the standard library that is intended to bypass specifying thorny details.

I'm more of a casual observer here, but I'm excited for the use cases that this unlocks.

Does this require/validate that the crate being compiled is empty? Of note is that if you're going to set a custom #[global_allocator], #[panic_handler], or similar, I think it would need to be set here.

I presume that the flag is intended to essentially just ensure that all of the public std/alloc/core symbols are included in and publicly exported from the resulting staticlib.

Unless this is intended to imply -Zbuild-std, you're going to get the precompiled stdlib object(s) with their configuration. This means release optimizations, unwinding support, and the target's baseline set of target features.

This section got deleted.

Since we put std into a static lib, it's probably sufficient and potentially desirable to state that rlibs using unstable rustc-private attributes (such as to define lang items) aren't guaranteed to link. The std staticlib gets special permission and guarantees of satisfying linking dependencies.

The RFC probably needs to define some overly strict sufficient way to get compatible rlibs, otherwise it's barely an improvement over status quo rlibs, since you're relying on unspecified implementation details that the rlibs are compatible.

Doesn't rustc already define how upstream dependencies must be compatibly compiled for compilation to succeed? Just indicate that definition as sufficient to get compatible rlibs.

I don't require that the crate be empty—the reference section tries to make clear that it's about not exporting any symbols, not that the lib.rs file is literally 0 bytes long. If you violate that rule by directly defining symbols in the libstd bundle, then the linkage behavior of those symbols is unspecified by this RFC. Standard library bundles are free to set any crate attributes that they wish.

Yep, exactly. If we were to change the way symbols are exported from libstd in the future, then this flag would be no longer a no-op.

Right, that's the behavior today. The language in the RFC is designed to keep the behavior sensible in the presence of -Z build-std and other potential future features.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.