rust-lang / wg-cargo-std-aware

Repo for working on "std aware cargo"
133 stars 8 forks source link

How to handle special object files? #46

Open ehuss opened 4 years ago

ehuss commented 4 years ago

Some targets ship pre-built object files needed to link on the target (such as "crt" files). How should these be handled?

There is some more detail in https://github.com/rust-lang/wg-cargo-std-aware/issues/30#issuecomment-529019350.

Some examples:

I don't know offhand how these magic object files are created in the first place. Is it feasible to build them from source? Are there any alternatives? If not, then maybe the only option is to require the user to install these pre-built targets, and Cargo can copy these .o files into the sysroot?

Lokathor commented 4 years ago

I've been following along here for GBA support. In that case, there is a crt0 style file, and you can build it directly from source. You could even say that it's preferred to build the crt0 from source.

petrochenkov commented 4 years ago

rs{begin,end}.o are built from source - https://github.com/rust-lang/rust/tree/master/src/rtstartup.

alexcrichton commented 4 years ago

One aspect of Cargo that will make this quite difficult is that Cargo, up to this point at least, is target-agnostic in as many ways as it can be, almost never hardcoding logic about particular targets. I think we've done this for things like multiple outputs with pdbs/emscripten js/etc, but otherwise there's very little target-specific logic in Cargo.

These object files are inherently target-specific, though, encoded into custom target specifications:

Most of these aren't actually built from Rust code, rs{begin,end}.o are the only ones I believe. Most others are copied from C sysroots when we build the compiler itself or assumed to just exist somewhere on the system.

To summarize my previous conclusion, I don't see a great way to handle this really other than letting rustc know that it's being built externally by Cargo, so rustc can't assume these objects exist and must rely on some form of an external toolchain providing them. Targets like musl/wasi are already weird in that they won't build by default because they try to find a static version of libc.a, which unless you externally configure won't "just work".

mati865 commented 4 years ago

I believe https://github.com/rust-lang/rust/issues/68887#issuecomment-633048380 will help here.

TL;DR All objects shipped with std that are not Rust based will be moved to the directory called self-contained. Rustc will be running either in self-contained mode (which uses objects from self-contained dir) or use external toolchain from the system (self-contained dir is not taken into account).

IMO building std should be the same as non self-contained mode so the only this it has to care about is building rs{begin,end}.o from Rust source. If that still poses problem rs{begin,end}.o can be easily dropped for x86_64 because they are no-op.