Description
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:
- 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.)
- Should we bring back the old behavior, at least in a limited set of cases?
- 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 tellrustc
that it needs to pass along parameters compatible with usingclang
as a linker? (But if that is the case, I do not seeclang
listed as one of the available values forlinker-flavor
) - 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 thecrt1.o
in the error could be used as a hint to look at the-nostartfiles
option as something to pass to the linker).