What might an official Rust target look like?
sunfishcode opened this issue · 8 comments
An official target could be much easier to use, with no mustang::can_run_here!()
macro, no target json file, and no -Z build-std
. And internally, it could avoid some of the linker hacks, and achieve much smaller code size, because it wouldn't need to force-link in all the libc symbols just to prevent the system libc from being linked in. And, this would be a natural moment to pick a new name for the target 😄 .
What might this look like? This issue is some early brainstorming in this space with many open questions, and more questions are welcome!
One big question is, should such a target use the c-scape C ABI compatibility layer?
-
If not:
- bytecodealliance/rustix#76
- #38
- Figure out a plan for mutex/rwlock, DNS resolution, and possible other stuff where mustang has more dependencies than std might want.
- Others?
-
If so:
- I wonder if it's possible to build up c-scape and all its dependencies, including std, into a single
#[crate_type = "staticlib"]
library, which we'd name "libc", and then we'd have the new Rust target use that. That would mean two copies of std present in resulting programs, which might present some tricky issues, and very likely produces large binaries, but if it's not too tricky this might be a faster path to getting something working while making relatively few changes to Rust itself. And then we could work on eliminating c-scape gradually over time.
- I wonder if it's possible to build up c-scape and all its dependencies, including std, into a single
That would mean two copies of std present in resulting programs, which might present some tricky issues, and very likely produces large binaries
You will get symbol conflicts if both std copies are identical. They need to have a different -Cmetadata
for that to work, which is going to be hard to integrate into the rust build system and -Zbuild-std
. Especially the later would be hard I think.
You will get symbol conflicts if both std copies are identical. They need to have a different
-Cmetadata
for that to work, which is going to be hard to integrate into the rust build system and-Zbuild-std
. Especially the later would be hard I think.
I tried a quick experiment:
- Build c-scape with a
*-mustang-*
target andcrate-type = ["staticlib"]
, which produces a libc.a. - Define a new custom target named
*-different-*
, that doesn't know anything about mustang, except that it links in the libc.a that we just built. Most ofstd
doesn't conflict because it gets different hash strings in the mangled names, however there are multiple-definition errors on some non-mangled names:__rust_alloc
,__rust_dealloc
,__rust_realloc
,__rust_alloc_zeroed
,__rust_alloc_error_handler
__rust_drop_panic
,__rust_foreign_exception
rust_begin_unwind
,rust_panic
,rust_oom
__rdl_alloc
,__rdl_dealloc
,__rdl_realloc
,__rdl_alloc_zeroed
__rdl_oom
,__rg_oom
You could maybe add the support for mustang
in the libc
crate, like a reexport of all c-scape
functions. So that you wouldn't link with the libc
of the OS while allowing crate that relies on the libc
crate to continue to work like their were doing before.
But that seems like a lot of work, not sure it's worth it.
This could maybe also be extended to allow "direct" access to the underline safe functions of rsix
, ... without even adding it to the Cargo.toml
; extern crate rsix
with use rsix::io
?
Maybe we can replace the libc
dependency of std
with an unconditional dependency on c-scape
for all Unix targets. c-scape
would then start with two configs, with one just wrapping libc
and the other one wrapping rsix
.
c-scape does have the beginnings of a mode where it's just a libc wrapper; see the libc!
macro in c-scape, which doesn't fully work yet, but might be made to do something like this.
I think the answer to my question above is: why not both?
Long-term, I think we don't want everything built on the c-scape C compatibility layer, which in theory means porting std to rustix. I've now started an experiment for this. We'll see how that shapes up.
c-scape is still valuable though, both as a way of getting more things running on origin/rustix sooner, and even long-term, as C compatibility for crates that link with C code. So if we can figure out more convenient ways of using it, those make sense to pursue too.
This sounds great. rustix
also has a libc
feature, so I thing the best way to go would be to first try to get the rustix
port into the official standard library. This should greatly reduce the number of functions from libc
which are actually called. In a next step, one could then try to redirect all reference of libc
via one common module. In addition, one might want to fork the currentlibc
in a new libc
and a smaller libc-freestanding
library (libc
reexporting it, this should be doable in a backward compatible manner). libc-freestanding
would only define the C primitive type aliases and the things defined in the "freestanding" header files ("float.h", "iso646.h", "limits.h", "stdarg.h", "stdbool.h", "stddef.h", "stdint.h"), which even "mustang" may want to define.
To my knowledge, no one is actively working on this, so I'm closing this issue for now. If anyone is interested, please reach out.