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

wasm32-unknown-unknown build as part of rustc contains object files for the wrong architecture when using GCC #732

Open
emilazy opened this issue Nov 9, 2024 · 6 comments

Comments

@emilazy
Copy link

emilazy commented Nov 9, 2024

Hi there, I’m not sure if I should report this here or in rust-lang/rust, so please let me know if I need to move this report elsewhere.

When investigating issues with the Nixpkgs rustc build, we discovered that when enabling the wasm32-unknown-unknown target on Linux, the libcompiler_builtins-*.rlib built for that platform contained object files for the architecture the compiler is being built for, rather than WASM ones. These correspond to the C‐based compiler-rt intrinsics.

I spent hours assuming this was purely a bug with our build environment until I looked at what rustup is shipping for wasm32-unknown-unknown:

45c91108d938afe8-cmpti2.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), with debug_info, not stripped

I can’t seem to induce Rust to try and link with these – whenever I do something that ought to use one of the intrinsics it just open‐codes it into the output WASM – but this seems kind of bad? When this crate is built with a Clang‐based environment, it passes --target and they’re built for the right platform, but it will also happily use a single‐target GCC and build for the entirely wrong platform. (It’s also not entirely clear to me how the Clang‐based build is meant to work, as the compiler-rt C files depend on libc headers despite the platform being freestanding; it seems to at least work by coincidence on our Clang‐based Darwin build, but fail in exciting ways if we try to use Clang on Linux.)

If these C‐based intrinsics are never used on wasm32-unknown-unknown, then they should probably not get compiled in the first place, but if they matter then it seems like they’re currently broken on GCC‐based environments.

@bjorn3
Copy link
Member

bjorn3 commented Nov 9, 2024

GCC doesn't support wasm at all, so building a fully optimized version of compiler-builtins for wasm requires using clang. It should be possible to configure clang as C compiler just for wasm32-unknown-unknown in the config.toml file that contains all build configuration for building rustc while still using GCC for the rest. There is also an option there to disable optimized compiler builtins (which skips building C entirely for compiler-builtins), but this can only be disabled globally and thus would make the compiler itself a bit slower too.

@emilazy
Copy link
Author

emilazy commented Nov 9, 2024

Right. But it at least seems like a flaw in the build script that it will currently happily guess that it should use GCC (for, most likely, the platform that rustc is being compiled to run on – and with no target flags, of course, since GCC isn’t multi‐target) to build compiler-builtins and build everything for the wrong architecture without realizing that anything is amiss (and then separately a flaw in the builds for the official binary distributions that they don’t set up the appropriate Clang for the WASM builds, but I don’t know where I’d report that).

FWIW it seems like this problem was exposed by #566 and the motivation there was compatibility with C code, which would make sense with my experience that I couldn’t find any way to get Rust to try and call the broken code.

@bjorn3
Copy link
Member

bjorn3 commented Nov 9, 2024

Right. But it at least seems like a flaw in the build script that it will currently happily guess that it should use GCC (for, most likely, the platform that rustc is being compiled to run on – and with no target flags, of course, since GCC isn’t multi‐target) to build compiler-builtins and build everything for the wrong architecture without realizing that anything is amiss (and then separately a flaw in the builds for the official binary distributions that they don’t set up the appropriate Clang for the WASM builds, but I don’t know where I’d report that).

The cc crate (which most crates use to build C code) by default attempts to use gcc or clang as C compiler even when cross-compiling. If you need another C compiler in general or for a specific target, you have to tell it using an env var. Rust's build systems sets this env var when you specify a C compiler for your target in config.toml.

@emilazy
Copy link
Author

emilazy commented Nov 9, 2024

Fair enough, although using unprefixed gcc by default when cross‐compiling is strange to me as it’s essentially guaranteed to produce code for the wrong architecture (with clang it’s fine as -target is passed, of course). Do you know where I should report the official toolchain binaries being miscompiled due to this?

@bjorn3
Copy link
Member

bjorn3 commented Nov 9, 2024

I missed the part of your message that this also effects the official toolchain builds. This probably will have to be fixed in the build system of rust, so https://github.com/rust-lang/rust/issues would be the best place to report this.

@emilazy
Copy link
Author

emilazy commented Nov 9, 2024

Thanks; I’ve opened rust-lang/rust#132802. The fallback compiler behaviour still seems somewhat broken to me in a cross‐compilation context – hence both Nixpkgs and the Rust project itself ending up with silently broken builds – but I suppose that’s more of a bug in the cc crate if anything, so this can be closed if you don’t think there’s anything to be done on the compiler-builtins end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants