summary refs log tree commit diff
path: root/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-14 13:28:21 +0000
committerbors <bors@rust-lang.org>2024-04-14 13:28:21 +0000
commita8a88fe5243cbeb37d8a9de8c5ca63136c0604b0 (patch)
tree4af434108516a24fcd24765b66f1f91aa273d254 /compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
parent78bc0a5656337478cb4163d01ee4429bab5087a9 (diff)
parent87e1dd0dfdd7c4d5e2dba8ce12c619dd2bf73d9c (diff)
downloadrust-a8a88fe5243cbeb37d8a9de8c5ca63136c0604b0.tar.gz
rust-a8a88fe5243cbeb37d8a9de8c5ca63136c0604b0.zip
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 'compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp')
0 files changed, 0 insertions, 0 deletions