Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider adding Linux targets that don't depend on libc #2610

Open
japaric opened this issue Dec 9, 2018 · 61 comments
Open

Consider adding Linux targets that don't depend on libc #2610

japaric opened this issue Dec 9, 2018 · 61 comments
Labels
A-libc Proposals relating to the libc crate. A-target Target related proposals & ideas T-compiler Relevant to the compiler team, which will review and decide on the RFC.

Comments

@japaric
Copy link
Member

japaric commented Dec 9, 2018

e.g. x86_64-linux (or x86_64-unknown-linux-rust).

These would be the spiritual successor of steed: a standard library, free of C dependencies, for Linux systems. Steed implemented (or planned to) the Rust standard library using raw Linux system calls instead of libc's API. These libc-less targets would also implement std using raw system calls.

Even though steed has been inactive for over a year people continue to star it on GitHub and currently has over 500 stars so it seems there's still interest for something like it.

What we learned during development is that maintaining a standard library out of tree is a lot of work because things get quickly out sync so if there's still interest for something like steed I would recommend writing an RFC to add support for libc-less targets (e.g. x86_64-linux) to rust-lang/rust; this would be equivalent to importing and developing steed as part of rust-lang/rust.

An RFC is also a good way to (re-)evaluate the ROI of making a libc-less standard library. One of the goals of steed was hassle-free cross compilation but today that's solved by the Linux/MUSL targets + rust-lld (works on stable). The other goal was better optimizations (plain LTO doesn't optimize across FFI) but cross-language LTO is a now thing (-Z cross-lang-lto). There may be less costly ways to achieve the same results.

The rest of this post describes the status of steed as of 2017-10-20 (date of last commit).

What we had working:

  1. standard I/O (std::io::{stdin,stderr,stdout})
  2. filesystem operations (std::fs)
  3. collections (std::collections) (but see (a) below)
  4. std::sync::Mutex (courtesy of parking_lot)
  5. std::env
  6. UDP and TCP sockets (std::net) (but see (d) below)
  7. minimal support for threads and TLS
  8. #[test] support (but see (c) below)

You can check the examples directory to get an idea of what you could write with it.

What was missing:

a. a proper allocator. steed used a bump pointer allocator that never freed memory
b. all the math stuff (e.g. f32::sin). These days one can use libm.
c. unwinding, all the steed targets used -C panic=abort
d. hostname lookup
e. errno. It was unclear whether we should implement it or not. It seems to only be required by std::io::Error::last_os_error. Linux system calls have a Result-like API so errno is not required to propagate errors from syscalls to the std API.

and much more stuff; you can check the issue tracker for the full list.


cc @tbu- @briansmith

@mark-i-m
Copy link
Member

mark-i-m commented Dec 9, 2018

This sounds really cool! However, I think you may be underestimating how much work this is. There would also need to be collaboration with kernel developers about system calls and stuff.

@lorenz
Copy link

lorenz commented Jan 1, 2019

@mark-i-m I agree that it is quite a bit of work, but there is no need for collaborating with kernel devs. The syscall interface is considered stable and they treat any change that'll break userspace as a bug. Go has successfully implemented this strategy on all OSs they support. So I'd argue it is pretty doable and in my opinion desirable.

@tbu-
Copy link
Contributor

tbu- commented Jan 1, 2019

This sounds really cool! However, I think you may be underestimating how much work this is. There would also need to be collaboration with kernel developers about system calls and stuff.

Most of the stuff was already in place, as you can see in @japaric's comment. :)

@mark-i-m
Copy link
Member

mark-i-m commented Jan 2, 2019

@lorenz Yes, you are right, but what I mean is that if we want to influence the syscall interfaces to make them more Rust-friendly we would need to interact more with the kernel devs...

@lorenz
Copy link

lorenz commented Jan 4, 2019

@mark-i-m What do you have in mind that you want changed? The syscall interface is totally usable from Rust and is in various ways a better fit than libc itself.

@mark-i-m
Copy link
Member

mark-i-m commented Jan 4, 2019

Admittedly, I haven't yet gotten to thinking extensively about this, but mainly my thinking is that syscalls often don't even attempt to by safe, so adding good Rust wrappers around them is either painful or inefficient.

For example, it is hard to write a good safe wrapper for mmap because it can do so many things; encoding all of them into efficient zero-cost abstractions is hard. There are also a bunch of syscalls that depend on C-defined structs/types (and their layouts), e.g. clock_get*, sched_setaffinity. (EDIT: actually, I'm not sure if these structs/types are just parts of libc... so I might be wrong there...)

@lorenz
Copy link

lorenz commented Jan 4, 2019

But this is not about implementing all possible safe uses of (for example) mmap, but just about reimplementing the standard library on top of syscalls which limits the scope to these specific operations. Also structs with C layout are no problem in Rust (we have #[repr(C)]) and are a sensible choice for a kernel since they are interoperable with everything. The kernel people will never maintain a separate syscall interface just for a specific programming language.

@mark-i-m
Copy link
Member

mark-i-m commented Jan 4, 2019

The kernel people will never maintain a separate syscall interface just for a specific programming language.

No, but they do talk with e.g. libc maintainers to discuss interfaces, libc support, etc.

But this is not about implementing all possible safe uses of (for example) mmap, but just about reimplementing the standard library on top of syscalls which limits the scope to these specific operations.

That's true, but this is also an opportunity to expose the kernel ABI in a safer way, although that doesn't seem to be the intent of this issue...

@SimonSapin
Copy link
Contributor

Any newly-proposed syscall will at best be present in the next kernel version, but it’ll be a number of years before you can usefully ship a program that just assumes it is present.

@briansmith
Copy link

Any newly-proposed syscall will at best be present in the next kernel version, but it’ll be a number of years before you can usefully ship a program that just assumes it is present.

Yes, but Rust can take advantage of them right away by falling back to something else when it receives ENOSYS (or whatever), without having to rely on convincing glibc/musl maintainers to do so.

@SimonSapin
Copy link
Contributor

Sure but if a fallback is needed anyway there is no point in doing all this only "to make them more Rust-friendly", is there? (As opposed to, say, a performance optimization.)

@joshtriplett
Copy link
Member

@mark-i-m It sounds like you're interested in something different than this is proposing. @japaric is proposing a standard library that's equivalent to the current std but without linking to the platform libc, by calling existing syscalls directly. That's a useful goal that many people want, and it doesn't involve changes to syscalls in any way.

If someone wanted to add new syscalls to Linux, for whatever reason, that would be outside the scope of this proposal.

@joshtriplett
Copy link
Member

As a separate thought, for a target like this, we could theoretically have a libc-compatible C library implemented in Rust, and then link C programs to that library. We don't need that, but it would make for an interesting future addition to this target.

@Darkspirit
Copy link

Darkspirit commented Mar 15, 2019

libc-compatible C library implemented in Rust

https://gitlab.redox-os.org/redox-os/relibc#relibc
https://github.com/redox-os/relibc

"relibc is a portable POSIX C standard library written in Rust."

It is under heavy development, and currently supports Redox and Linux.

The motivation for this project is twofold: Reduce issues the redox crew was having with newlib, and create a safer alternative to a C standard library written in C. It is mainly designed to be used under redox, as an alternative to newlib, but it also supports linux syscalls via the sc crate.

Supported OSes
Redox OS
Linux

Supported architectures
x86_64
Aarch64

Edit:
Just found this: This tries to add an x86_64-unknown-linux-relibc target:
mati865/rust#1 (comment)
mati865/rust@master...relibc
rust-lang/libc@master...mati865:relibc

@newpavlov
Copy link
Contributor

Looking forward to playing with this libc-free target! I wonder if it will be possible to later remove x86_64-unknown-linux reliance on libc after experimenting on a separate target?

@newpavlov
Copy link
Contributor

a proper allocator. steed used a bump pointer allocator that never freed memory

IIUC elfmalloc can be used here.

@zmlzm
Copy link

zmlzm commented Jun 26, 2019

There is a news : A libc in LLVM

@dvc94ch
Copy link

dvc94ch commented Aug 23, 2019

Does adding new targets require a rfc? Or were large changes required to the codebase?

@elichai
Copy link

elichai commented Oct 18, 2019

Hi,
I've started working on exactly this but with a bit of a different mindset.

My goal is to push rust safety's guarantees as much as possible. currently it stops at the entrance to libc. so I'm writing a rust libc implementation.

I already seen parts of libc that have UB potential if you misuse them. something that rust can easily solve.

But. I want this to be a usable target, so I propose to make a new target that will still link to libc, but will slowly move away from using libc, currently I see 3 areas where libc is actually needed:

  1. There are users who call libc and then use std::io::Error::last_os_error() for the errno. so we need to keep this working(potentially until a new edition / rust 2.X where we could deprecate this?)
  2. libunwind.
  3. pthreads.

For the first one, I personally think it's fine, because then LTO should remove libc for users who don't use that part of libstd.

For the second one I think the right path forward is a rewrite in rust. but I understand that this can take a while.

For the third one, this should be a public discussion. do we want to just copy the pthreads implementation? or do we want to invent our own threads that makes more sense for rust? if so how will that affect FFI to C?

Until these questions are answered I still think it's a big win to have a target that for the short run tries to minimize the calls to libc but for the long run plans to remove it completely.

Would love people's feedback on this.
Already made a list of all the calls to libc in rust's libstd, and a start of how I think the API can/should look like https://github.com/elichai/syscalls-rs

To emphasize. I don't want just a musl rewrite in rust with big blobs of unsafe. My whole point is to extend the safety because:
A. libstd dev's can also make mistakes, so let's get them a safer API like what they're doing for the users in all other aspects.
B. A lot of users in the wild are calling libc, we can make this safer.
C. I hope that one day we'll get memory safety through the whole stack, and I think this is the next stage for rust.

@SimonSapin
Copy link
Contributor

I'm writing a rust libc implementation.

To me “libc implementation” means something specific. It provides C APIs as defined in the C standard and POSIX, and tries to be compatible with other implementations in the same way that musl and glibc are compatible with each other. relibc is a libc implementation written in Rust.

It seems that you don’t mean that, but rather something that “spiritually” fills a role similar to that of libc in communicating with the kernel through syscalls and providing higher-level abstractions?

A lot of users in the wild are calling libc, we can make this safer.

Or do you mean something used not instead of libc, but an abstraction on top of it?

how will that affect FFI to C?

As far as I can tell, steed and this issue are about programs that do not use C at all. As soon as you have C code that code needs a libc implementation (as defined above), so there isn’t much point in avoiding it in libstd, in my opinion.

@elichai
Copy link

elichai commented Oct 18, 2019

I'm talking about a rust replacement for libc. I'm not planing of exposing FFI functions to C.
The point is to have something like "libr" meaning all the libc functionality but for rust. because we're not C. So currently I'm trying to give the same functions but have rust safer function signatures to them.

I hope that in the long run it will prove itself safer and overall better. then we'd want to use it in libstd by default even if you still link to C code that'll use libc.

@SimonSapin
Copy link
Contributor

If you’re changing signatures anyway, it doesn’t have to stay close to “the same functions” at all. Do you need any well-defined abstraction between libstd’s public API and syscalls? Why shouldn’t std::fs::File be the safer signature for open(2)?

@elichai
Copy link

elichai commented Oct 18, 2019

It could, although open is used directly also in flock::Lock.
but this is just 1 syscall. there are some syscalls scattered all over libstd.
this could be a simple drop in replacement for most of them. (maybe a bit more gymnastics for flags etc.)

and the point is levels of abstractions, you can have a function that calls directly 4 syscalls and handles all their errors etc. and then say that that function is the safer api. but for good better abstractions it's better to split each syscall and the handling of the data/errors to it's own file. that way it's also way easier to review carefully.

@dvc94ch
Copy link

dvc94ch commented Oct 18, 2019

If you’re changing signatures anyway, it doesn’t have to stay close to “the same functions” at all. Do you need any well-defined abstraction between libstd’s public API and syscalls? Why shouldn’t std::fs::File be the safer signature for open(2)?

There is also a lot of stuff you can't do with rusts stdlib at the moment, some which I've needed recently are:

  • acquiring file locks
  • setting ecn on udp packets
  • dropping capablitities
  • signal handling
  • epoll

While there are libraries doing these things, they use the libc crate and are usually plastered with unsafe code.

@jonas-schievink jonas-schievink added A-libc Proposals relating to the libc crate. A-target Target related proposals & ideas T-compiler Relevant to the compiler team, which will review and decide on the RFC. labels Nov 19, 2019
@jeff-hykin
Copy link

jeff-hykin commented Oct 22, 2021

Is Mustang a good idea? If so, how would you use it? Is Mustang the wrong approach? Is it confusing? Is this issue not worth solving anymore now that Rust has musl targets and cross-language LTO? I'm interested in any feedback people would like to share, including negative feedback.

@sunfishcode

Every programming problem I have, when I track it down to it's source, seems to originate with C/C++. It wasn't till a few years ago that I realized how seriously everything I do somehow, some way, has C/C++ as a foundation. Basically every zero-day exploit in my cyber security class is because of something stupid in C/C++. And it goes well beyond security, the more I dive into C++ the more terrible stuff I find. When I found out even Rust needed the clib, it was like seeing an iron-clad fortress only to look closer and see it was being held up by sticks, ducktape, and prayers.

A perfect example is two days ago I was trying to convert an RGB array to a PNG ... in Python. All the python libraries for png's; they have messy C/C++ dependencies. I wanted to see how the image conversion was implemented so I go to libpng's website. And whatdyahknow, there's a warning about a major security flaw right there at the top of the page.

IMG_20211022_075506_535.jpg

But I don't even care about security; I just care about correctness and clarity. Libpng was your typical big messy confusing C codebase. So what do I do? I search for a Rust PNG lib. (Again, I'm coding Python, yet my workflow is pulling me into lower levels of code). Not only was there a pure Rust implementation, not only does it avoid ever using unsafe, but most importantly to me: I can fricken understand the code at a high level. I have about 5 years of frequent C++ experience, and about 3 months of Rust experience, yet when I want to understand an implementation I go to the Rust codebase.

TLDR: Musl is great and all, but I actually want to be able to read, understand, and trust the implementation, not just wrap up my code into a static binary. And if there was one thing that SHOULDN'T be C in my opinion it would be the very foundation of Rust itself.

@newpavlov
Copy link
Contributor

@sunfishcode
I am a big fan of pure-Rust targets (e.g. I think we also should have a pure Rust WASI target). I think that Mustang is a great initiative for prototyping libc-free Rust std and its achievements are laudable, but I believe it should be eventually merged into Rust proper, otherwise it risks the same fate as steed. Not only the current approach is less ergonomic compared to using MUSL, but also has discoverability issues.

@sunfishcode
Copy link
Member

Thanks for the feedback! I appreciate hearing people's thoughts :-).

A few updates: @nivkner implemented fork+exec support, and @nivkner and @Urgau added support for sched_affinity, so Mustang can now run std::process::Command, and it can even now run ripgrep in some cases! Some features are still missing though.

I've also started a branch to explore another side of the space, porting Rust's std to rustix. See here for the current status.

@cgwalters
Copy link

From my PoV, most of the important projects for which I use Rust will have C/C++ linked in process for the forseeable future. I know I'm not alone in that.

I can certainly understand the desire for something like mustang, but I think the concern boils down to: is the benefit of adding this new target worth the maintenance overhead?

A somewhat related concern I have is proliferation and duplication of low-level crates. Most in the community seem OK with the way crates.io works versus having a larger standard library. But there are tradeoffs with this. For example, my company's software needs to be multi-arch across beyond just aarch64 and x86_64, also to ppc64le and s390x. Historically, they mostly needed to adapt to changes in the Linux kernel and glibc. Now of course in the Linux ecosystem there's also musl and bionic, but rustix is adding another one. That's not without cost.

rustix heavily overlaps with nix - which is a dependency of tokio for example.

Related to this, the distributed crates.io ecosystem also means that there's much less uniformity in things like continuous integration systems. For example, while it's great that rustix' CI flow tests many platforms, it does not cover all of the tier 2 targets (including the two I need to support mentioned above, ppc64le and s390x). If rustix is a dependency of std, this type of thing would need to change.

Yet another related issue here - and this is my personal opinion - is lack of uniformity in peer review. Changes to rust-lang/rust require peer review, as do changes to glibc. Now, you are clearly an amazingly prolific code writer. But as far as I can tell, most code changes to rustix merge without any peer review. I would hope that as part of having Rust std depend on rustix, this could be improved; that seems like a natural evolution from "PoC" to production.

All these concerns aside, from my PoV all the code and design in the whole dependency chain you've created from cap-std down to rustix, the safe IO bits etc. looks quite good! I still have on my TODO list trying out switching from the openat crate and converting some of my nix usage to rustix.

cgwalters added a commit to cgwalters/ostree-rs-ext that referenced this issue Jan 4, 2022
This is safer and may actually fix a race condition I've seen sometimes
in CI runs.  Part of investigating using rustix (and cap-std) in
our section of the ecosystem (xref rust-lang/rfcs#2610).
@algesten
Copy link

algesten commented Jan 4, 2022

Surely if Rustix became a dependency of std, it would cease being an external crate and merge onto the main rust tree?

@cgwalters
Copy link

Another related thing here is basically that the libc developers are saying "you either use libc or you don't": best encapsulated by this thread: rust-lang/rust#89522 (comment)

Right now, rustix seems to have a clean design where it can be configured in either way, which is good. But I am sure the temptation will be high in some cases to start making direct syscalls in the libc backend when e.g. libc is lagging on binding a particular syscall. And that brings the issues in the above thread.

Again though I'll say rustix is cool (as is the mustang experiment), and from my PoV there is a clear need for it to exist given the fact that we need a high level interface in std that also supports Windows, but we also need to have external crates which do Unix and very Linux specific things. So it does probably make sense to take the next step and have std depend on rustix.

But, perhaps instead it makes sense to try to push for using rustix instead of nix in the ecosystem ahead of using it in std? I previously looked at this a bit in this discussion, and I can try some more (edit: OK did some over here).

@sunfishcode
Copy link
Member

@cgwalters

I very much agree. These projects are at a "let's talk about what we might want this to look like" phase, rather than any kind of official proposal, or even a pre-RFC. They definitely have growing and maturing to do, both as codebases and as projects.

There are certainly costs in duplication and churn. But there are also costs in stagnation and not exploring. A theme I've seen come up in several places recently is that if one looks at the projects as being about just one goal, like "a libc-free Rust (on the one popular OS where that even makes sense)", or "micro-optimizing syscall wrappers (which aren't the part of syscalls which take most of the time)", it looks less interesting. The key is to look at the combined goals, which also include factoring out unsafe and error handling and raw pointers, exploring and promoting I/O safety down the stack, and building foundations for practical capability-based security, which is itself part of even larger goals.

As for starting with the ecosystem ahead of std, I've started a few things in this space too, and am interested in doing more. And I agree, it makes sense to do more of this before making any official proposals. At the same time, it seems useful to start the conversations about std too, because if we need to make major changes to support std, it's easier if we can get those changes started sooner rather than later.

cgwalters added a commit to cgwalters/ostree-rs-ext that referenced this issue Jan 6, 2022
This is safer and may actually fix a race condition I've seen sometimes
in CI runs.  Part of investigating using rustix (and cap-std) in
our section of the ecosystem (xref rust-lang/rfcs#2610).
cgwalters added a commit to cgwalters/ostree-rs-ext that referenced this issue Jan 6, 2022
This is safer and may actually fix a race condition I've seen sometimes
in CI runs.  Part of investigating using rustix (and cap-std) in
our section of the ecosystem (xref rust-lang/rfcs#2610).
@sunfishcode
Copy link
Member

Mustang is now using the new futex-based Mutex/RwLock/Condvar implementations that @m-ou-se recently developed for std instead of parking_lot, which avoids the need to do global allocation from within the locking primitives. This makes Mustang's global allocator setup much simpler. The 32-bit x86 port is now back online. And origin no longer needs a git dependency on a parking_lot fork so it's now updated on crates.io so we can read the docs on docs.rs.

@sunfishcode
Copy link
Member

I'm now placing the project to work toward Mustang becoming an official Rust target on hold. I'll continue to maintain it for the foreseeable future. If anyone has ideas about what they would like to see Mustang become, please reach out.

@rrnewton
Copy link

this is why I've started: https://github.com/elichai/syscalls-rs, which gives a rust-like API directly to syscalls ,

@elichai, one thing we've released as part of https://github.com/facebookexperimental/reverie is the "reverie-syscalls" crate, that provides one type-safe view of how to construct Syscall calls themselves (e.g. with proper argument types). Not sure how this compares with your effort or the nc crate, which seems to be receiving recent development.

It's designed for use with ptracers, so it would require some adaptation to be used to directly invoke syscalls, and maybe @jasonwhite can comment on whether that would make sense. It probably wouldn't be zero cost (without significant compiler optimization) because you do construct structs to represent the syscalls. But the macros used to derive these structs could probably also derive a direct function interface for invoking the syscalls, while retaining one source-of-truth for what are the syscalls, their numbers, and their argument types.

@rrnewton
Copy link

rrnewton commented Nov 18, 2022

I'm wondering if someone here can redirect me to the best place for building Rust no_std programs without libc (musl or gnu). That's a much less lofty goal than reimpleminting libc, as described throughout this issue.

It seems like Rust OS kernel projects have their own setup, but I'm not seeing any ergonomic way to just build a static binary that doesn't link libc (the way you can with gcc or clang -nostdlib). There isn't a x86_64-unknown-linux-nolibc target for example. So the nc library seems ideal for invoking some syscalls from a no_std/libc-free static binary, but that build mode doesn't seem to exist in an accessible form. Or am I missing something?

@Lokathor
Copy link
Contributor

If you don't want libc then you don't want to use linux either, so you probably want a binary target that ends with "none".

@azazar
Copy link

azazar commented Nov 18, 2022

libc != linux. Why should everyone want libc?

@sunfishcode
Copy link
Member

Mustang is able to build Rust programs on Linux without linking in any libc today. It's complete enough to run ripgrep, for example.

@estk
Copy link

estk commented Jun 7, 2023

I could not be more interested in this. My particular use case is: at $work we distribute software which links to a shared library in a dizzying array of exotic environments. It is a constant annoyance supporting these toolchains and system libraries.

Why not produce a library with musl statically linked you say? One such environment only supports dynamically linking native libraries. ☕ 👀

We temporarily solved this by compiling in a similarly ancient build environment and a now-aging rust toolchain which supports glibc 2.11 (https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html)

For less exotic target platforms we've now started using cargo-zigbuild which has allowed us to move some build infra to newer toolchains without precluding some backward glibc compatibility.

There are a number of reasons this situation is less than ideal:

  1. In order to produce a library which has the runtime compatibility claimed by rustlang, we need to use a third-party linker.
  2. Any rust binaries compiled elsewhere will almost certainly not work with our ancient build infra (musl does not guarantee posix compliance with the kernel we're using)
  3. Downstream users of our shared library cannot seem to keep straight which library belongs to which platform and seems to have, in some cases, given up and just used the one built with the most ancient toolchain.
  4. Obviously using a pinned rust toolchain is eventually untenable.

TLDR; Removing even one term from the exponential expansion of build target's is worth the effort. Aaand, in this case it's actually two terms the gnu term and the implied version of glibc.

@tgross35
Copy link
Contributor

tgross35 commented Dec 9, 2023

@sunfishcode it seems like you are working on eyra, which appears to be a version of Mustang that drops in place of std.

Have you considered writing an RFC to bridge rustc to this work? Not sure if this would be a target string or some other form of bridge, but it would be awesome to get some community feedback on the idea. Even if very incomplete, the entry level for a tier 3 target is very low.

Even if it turns out out Mustang / Eyra won't be brought in-tree, it would be great to open up discussion about how we could do libc-free targets (as opposed to here where discussion is mostly if we may want to do this)

@sunfishcode
Copy link
Member

@tgross35 It's my impression that if is still the most pertinent question here. I've read this whole thread, and numerous others, and am honestly still unclear about why people want such a thing, or indeed whether they even do substantially want it at all, as opposed to just thinking it sounds cool.

@estk
Copy link

estk commented Dec 9, 2023

@sunfishcode to answer you question: personally what lead me to explore a libc-free std was an attempt to reduce the number of targets my team's binary distribution had to support. We distribute binaries for pre libc 2.17 and I was hoping we could avoid abandoning libc 2.11 targets. As I'm sure you can guess, in exploring the practicality I realized:

  1. musl isnt going to work for us due to kernel compatibility, also its slow.
  2. cargo-zigbuild is pretty much exactly what we want for 2.17 and later targets.
  3. I recall reading somewhere that many sycalls are only officially supported if run by libc, and that libc puts a lot of effort into avoiding the syscall if at all possible.

Reasons I can think that folks would still want a libc-free std (aside from just "sounding cool")

  1. Binary size is P0 (and they dont count the libc already installed)
  2. Security, not subject to exploits in libc

FWIW I'd be much more interested in cargo-zigbuild getting pulled in than adding a libc-free target.

@sunfishcode
Copy link
Member

@estk It sounds like the topic here isn't addressing what you need. Which is fine; I just want to be clear about it.

Concerning your reasons folks might want a libc-free std:

  • If you care about code size but don't count libc because it's already installed, then as far as I can tell, you just want to use libc.
  • Eyra and its dependencies have a serious huge lot of unsafe code. It's unavoidable, doing what they're doing. There may be paths by which a different story could eventually become possible, but RiiRing libc is not at all a shortcut to safety.

@tgross35
Copy link
Contributor

tgross35 commented Dec 9, 2023

@tgross35 It's my impression that if is still the most pertinent question here. I've read this whole thread, and numerous others, and am honestly still unclear about why people want such a thing, or indeed whether they even do substantially want it at all, as opposed to just thinking it sounds cool.

I think a big part of that is because there isn't an actual plan, nobody really knows what the result would look like. What gets in-tree vs. external libraries, what is the entrypoint, do we do new target strings, how does this interact with LLVM, etc, are all questions that need to be answered. But it is tough to provide useful technical feedback about tradeoffs and expected work when there isn't something concrete to discuss.

Which is what I think an RFC would help solve. That would propose a meaningful direction, get feedback about feasibility, and wind up with something that team members need to give an opinionated respond to. It will give a better idea about what amount of interest comes from coolness vs. actually solving technical problems.

I really don't think anybody would say no to an experiment. The experiment just needs a definitive shape, as opposed to the handful of one-off proposals in this thread. Maybe a pre-RFC on IRLO could be a good starting point?

@sunfishcode
Copy link
Member

Starting a big public complex technical discussion without any goals isn't really my cup of tea, but don't let me stop anyone 😉.

@jeff-hykin
Copy link

jeff-hykin commented Dec 10, 2023

Reasons I can think that folks would still want a libc-free std

Maybe other people think that way but those are not at all why I want a libc-free binary.

  1. If anything I expect the binary to be bigger
  2. I agree with @sunfishcode , at this level basically everything needs to be wrapped in unsafe. While the syntax and tooling can still help with saftey, they'll be completely dwarfed by saftey from the current extensive testing of the normal libc.

I've read this whole thread, and numerous others, and am honestly still unclear about why people want such a thing

  • I want it to make work like the incredible cosmopolitan libc more realistic/possible for rustc
  • I want to be able to understand and validate code all the way down to system calls
  • I want to be able to fork/hack/tinker with everything using modern macros, instead of needing to call a libc black box
  • I'd like to be able to build an OS in rust that doesn't need a libc but still has access to std

Starting a big public complex technical discussion without any goals

goal: be able to downgrade, upgrade, or screw up the libc of a VM and have a binary still work as intended

I personally don't care all that much if it's integrated into rust official or not, I just want the capability.

@sunfishcode
Copy link
Member

I'll be unsubscribing from this thread for the foreseeable future after this comment.

One of the ways I imagine that I'll be able to tell that Eyra is ready to be proposed as an official Rust target is that there will be a different kind of conversation. It won't be about people trying to convince me of something. It will be about people using Eyra but maybe wanting it to be something more. Or, it'll be people who have tried Eyra and ran into trouble. Or they found it doesn't do something they need, and so on. Or maybe people who have a bigger idea of what Eyra could grow into. Or they have a real-world use case that they think Eyra could work for, and they have some questions. When those kinds of comments shape the conversation, that's when I'll know that this project makes sense.

@jeff-hykin
Copy link

I'll be unsubscribing from this thread for the foreseeable future after this comment.

:( okay

that's when I'll know that this project makes sense.

I appreciate the clarity.

In terms of focus, I think it makes sense. I'm subscribed to wasi stuff and see your name pop up all the time, so I know you do a lot of other really important work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-libc Proposals relating to the libc crate. A-target Target related proposals & ideas T-compiler Relevant to the compiler team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests