Repository: rust
Issue: Linker invocation for wasm32-unknown-unknown incompatibly changed between 1.66.1 and 1.67.1
Labels: A-linkage,P-medium,T-compiler,regression-from-stable-to-stable,O-wasm,C-bug

I ran this sequence of commands via `rustup` to install 1.66.1 and 1.67.1, as well as the target support for wasm32-unknown-unknown for each, and then tried to compile a `cdylib` for wasm32-unknown-unknown while *also overriding the linker*.

```
% rustup update 1.66.1
[...]
% rustup update 1.67.1
[...]
% rustup target add --toolchain 1.66.1 wasm32-unknown-unknown
[...]
% rustup target add --toolchain 1.67.1 wasm32-unknown-unknown
[...]
% echo > /tmp/hello.rs
% rustc +1.66.1 /tmp/hello.rs --crate-type cdylib --target wasm32-unknown-unknown -C linker=clang && echo success
success
% rustc +1.67.1 /tmp/hello.rs --crate-type cdylib --target wasm32-unknown-unknown -C linker=clang
error: linking with `clang` failed: exit status: 1
  |
  = note: "clang" "-Wl,-z" "-Wl,stack-size=1048576" "-Wl,--stack-first" "-Wl,--allow-undefined" "-Wl,--fatal-warnings" "-Wl,--no-demangle" "--target=wasm32-unknown-unknown" "-Wl,--no-entry" "hello.hello.4592d75c-cgu.0.rcgu.o" "hello.395fat3noigyayzs.rcgu.o" "-L" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libstd-4cc67ecdd38ec816.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libpanic_abort-d7aed05895fd3acd.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libdlmalloc-d614b689e44911c3.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/librustc_demangle-b67bdb405beac3e8.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libstd_detect-d35bb83dee339ae2.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libhashbrown-a91c75972ec9987b.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libminiz_oxide-cebf340576826f4d.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libadler-1dfefb8109e16570.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/librustc_std_workspace_alloc-fb56ca5e4fa7e885.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libunwind-7758a353f6e6c303.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libcfg_if-9fa968ba9e6d4f22.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/liblibc-6769bef7a67a1976.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/liballoc-5ef00dd564498f26.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/librustc_std_workspace_core-a025c7699298bef7.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libcore-028eb657858f49ce.rlib" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libcompiler_builtins-f9be42f11058bb31.rlib" "-L" "/home/pnkfelix/.rustup/toolchains/1.67.1-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib" "-o" "hello.wasm" "-Wl,--gc-sections" "-shared" "-nodefaultlibs"
  = note: clang: warning: argument unused during compilation: '-shared' [-Wunused-command-line-argument]
          wasm-ld-14: error: cannot open crt1.o: No such file or directory
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

```

I expected to see this happen: a command sequence that worked under 1.66.1 to continue working under 1.67.1

Instead, this happened: A linker failure that is somewhat inscrutable to a layperson.

----

Note: There *is* a relatively easy workaround available. Under 1.66.1  when passing `-C linker=clang`, the linker invocation also included the argument `-nostartfiles`. For some reason, that argument has gone away under 1.67.1 with this invocation sequence, but one can re-add it manually by passing `-C link-arg=-nostartfiles` into `rustc`.

The questions I have are:
 1. Why did this change between 1.66 and 1.67? Was it an expected change in behavior? (Why is this change good? Its not noted in the release notes that I saw.)
 2. Should we bring back the old behavior, at least in a limited set of cases?
 3. Is there a different invocation our users should be using when they override the linker, e.g. perhaps they should be using `-C linker-flavor=xxx` to tell `rustc` that it needs to pass along parameters compatible with using `clang` as a linker? (But if that is the case, I do not see `clang` listed as one of the available values for `linker-flavor`)
 4. Should we start investing in *post-processing* the linker-errors from `rustc` itself -- and still spit out those linker errors (because in the general case, the user *is* going to need to see them in order to make sense of what to do in reaction), but potentially also provide hints as to things to look into (e.g. in this case, maybe the `crt1.o` in the error could be used as a hint to look at the `-nostartfiles` option as something to pass to the linker).