diff options
| author | bors <bors@rust-lang.org> | 2024-04-14 13:28:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-14 13:28:21 +0000 |
| commit | a8a88fe5243cbeb37d8a9de8c5ca63136c0604b0 (patch) | |
| tree | 4af434108516a24fcd24765b66f1f91aa273d254 /library/std/src | |
| parent | 78bc0a5656337478cb4163d01ee4429bab5087a9 (diff) | |
| parent | 87e1dd0dfdd7c4d5e2dba8ce12c619dd2bf73d9c (diff) | |
Auto merge of #122268 - ChrisDenton:no-libc, r=Mark-Simulacrum
Link MSVC default lib in core
## The Problem
On Windows MSVC, Rust invokes the linker directly. This means only the objects and libraries Rust explicitly passes to the linker are used. In short, this is equivalent to passing `-nodefaultlibs`, `-nostartfiles`, etc for gnu compilers.
To compensate for this [the libc crate links to the necessary libraries](https://github.com/rust-lang/libc/blob/a0f5b4b21391252fe38b2df9310dc65e37b07d9f/src/windows/mod.rs#L258-L261). The libc crate is then linked from std, thus when you use std you get the defaults back.or integrate with C/C++.
However, this has a few problems:
- For `no_std`, users are left to manually pass the default lib to the linker
- Whereas `std` has the opposite problem, using [`/nodefaultlib`](https://learn.microsoft.com/en-us/cpp/build/reference/nodefaultlib-ignore-libraries?view=msvc-170) doesn't work as expected because Rust treats them as normal libs. This is a particular problem when you want to use e.g. the debug CRT libraries in their place or integrate with C/C++..
## The solution
This PR fixes this in two ways:
- moves linking the default lib into `core`
- passes the lib to the linker using [`/defaultlib`](https://learn.microsoft.com/en-us/cpp/build/reference/defaultlib-specify-default-library?view=msvc-170). This allows users to override it in the normal way (i.e. with [`/nodefaultlib`](https://learn.microsoft.com/en-us/cpp/build/reference/nodefaultlib-ignore-libraries?view=msvc-170)).
This is more or less equivalent to what the MSVC C compiler does. You can see what this looks like in my second commit, which I'll reproduce here for convenience:
```rust
// In library/core
#[cfg(all(windows, target_env = "msvc"))]
#[link(
name = "/defaultlib:msvcrt",
modifiers = "+verbatim",
cfg(not(target_feature = "crt-static"))
)]
#[link(name = "/defaultlib:libcmt", modifiers = "+verbatim", cfg(target_feature = "crt-static"))]
extern "C" {}
```
## Alternatives
- Add the above to `unwind` and `std` but not `core`
- The status quo
- Some other kind of compiler magic maybe
This bares some discussion so I've t-libs nominated it.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/lib.rs | 3 | ||||
| -rw-r--r-- | library/std/src/os/unix/net/addr.rs | 2 | ||||
| -rw-r--r-- | library/std/src/os/unix/net/ancillary.rs | 2 | ||||
| -rw-r--r-- | library/std/src/os/unix/net/datagram.rs | 4 | ||||
| -rw-r--r-- | library/std/src/os/unix/net/listener.rs | 8 |
5 files changed, 11 insertions, 8 deletions
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index e9de3b77670..72ae38cfa20 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -431,6 +431,9 @@ extern crate test; #[allow(unused_imports)] // macros from `alloc` are not used on all platforms #[macro_use] extern crate alloc as alloc_crate; + +// Many compiler tests depend on libc being pulled in by std +// so include it here even if it's unused. #[doc(masked)] #[allow(unused_extern_crates)] extern crate libc; diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 1787eba0ef8..79f2c365025 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -11,7 +11,7 @@ use crate::{fmt, io, mem, ptr}; #[cfg(not(unix))] #[allow(non_camel_case_types)] mod libc { - pub use libc::c_int; + pub use core::ffi::c_int; pub type socklen_t = u32; pub struct sockaddr; #[derive(Clone)] diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs index 1d279d6adbc..0597fdcbd72 100644 --- a/library/std/src/os/unix/net/ancillary.rs +++ b/library/std/src/os/unix/net/ancillary.rs @@ -20,7 +20,7 @@ use crate::sys::net::Socket; ))] #[allow(non_camel_case_types)] mod libc { - pub use libc::c_int; + pub use core::ffi::c_int; pub struct ucred; pub struct cmsghdr; pub struct sockcred2; diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index df698c17f6c..b29f9099a11 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -34,7 +34,7 @@ use libc::MSG_NOSIGNAL; target_os = "haiku", target_os = "nto", )))] -const MSG_NOSIGNAL: libc::c_int = 0x0; +const MSG_NOSIGNAL: core::ffi::c_int = 0x0; /// A Unix datagram socket. /// @@ -317,7 +317,7 @@ impl UnixDatagram { fn recv_from_flags( &self, buf: &mut [u8], - flags: libc::c_int, + flags: core::ffi::c_int, ) -> io::Result<(usize, SocketAddr)> { let mut count = 0; let addr = SocketAddr::new(|addr, len| unsafe { diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs index 31286a906ea..7e53acbc387 100644 --- a/library/std/src/os/unix/net/listener.rs +++ b/library/std/src/os/unix/net/listener.rs @@ -79,14 +79,14 @@ impl UnixListener { target_os = "espidf", target_os = "horizon" ))] - const backlog: libc::c_int = 128; + const backlog: core::ffi::c_int = 128; #[cfg(any( target_os = "linux", target_os = "freebsd", target_os = "openbsd", target_os = "macos" ))] - const backlog: libc::c_int = -1; + const backlog: core::ffi::c_int = -1; #[cfg(not(any( target_os = "windows", target_os = "redox", @@ -138,9 +138,9 @@ impl UnixListener { unsafe { let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?; #[cfg(target_os = "linux")] - const backlog: libc::c_int = -1; + const backlog: core::ffi::c_int = -1; #[cfg(not(target_os = "linux"))] - const backlog: libc::c_int = 128; + const backlog: core::ffi::c_int = 128; cvt(libc::bind( inner.as_raw_fd(), core::ptr::addr_of!(socket_addr.addr) as *const _, |
