rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.68k stars 12.63k forks source link

emcc and wasm-ld can't link our ui tests for `wasm32-unknown-emscripten`? #131666

Open workingjubilee opened 1 day ago

workingjubilee commented 1 day ago

Perhaps I'm holding it wrong? About a fifth of the rustc UI test suite to fail on wasm32-unknown-emscripten when trying to run ./x.py test --target wasm32-unknown-emscripten. In all cases we get an error like this:


error: linking with `emcc` failed: exit status: 1
   |
   = note: "emcc" "-s" "EXPORTED_FUNCTIONS=[\"_main\"]" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/test/ui/array-slice-vec/vector-no-ann-2/a.vector_no_ann_2.86c223511763191d-cgu.0.rcgu.o" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/test/ui/array-slice-vec/vector-no-ann-2/a.1t3t8w654vioaffrv2c1spxg2.rcgu.o" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libstd-6499696fb99a9577.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libpanic_unwind-0c3cc3cd32c2b4b3.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libmemchr-e7a6f41ef20fcc54.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/librustc_demangle-d35e921e53f26e9e.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libstd_detect-a7a77daaad248f5e.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libhashbrown-e0e54cdb8e75fbf2.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/librustc_std_workspace_alloc-9f19c89c353a136f.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libminiz_oxide-ffd1c27bbffc4236.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libadler-4452dbe2564d6cb8.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libunwind-684258862f7c352d.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libcfg_if-0f4ad8f59845e58a.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/liblibc-2be890f74433405e.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/liballoc-48460e2c05fc2c62.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/librustc_std_workspace_core-841075126ac27f05.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libcore-ee3c0a07d74de06f.rlib" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/libcompiler_builtins-c113413e38c4b290.rlib" "-l" "c" "-B/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld" "--target=wasm32-unknown-emscripten" "-s" "DISABLE_EXCEPTION_CATCHING=0" "-L" "/home/jubilee/rust/rustc/build/wasm32-unknown-emscripten/native/rust-test-helpers" "-L" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/test/ui/array-slice-vec/vector-no-ann-2/auxiliary" "-L" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/wasm32-unknown-emscripten/lib/self-contained" "-o" "/home/jubilee/rust/rustc/build/x86_64-unknown-linux-gnu/test/ui/array-slice-vec/vector-no-ann-2/a.wasm" "-O2" "-g0" "-sABORTING_MALLOC=0"
   = note: wasm-ld: error: /home/jubilee/.emscripten_cache/sysroot/lib/wasm32-emscripten/libstandalonewasm.a(__main_void.o): undefined symbol: main
jieyouxu commented 1 day ago

Does this target use some different main symbol name?

jieyouxu commented 1 day ago

... do we need to pass --no-entry to lib builds? https://github.com/emscripten-core/emscripten/issues/9640

@workingjubilee can you check if (some of) the failing tests are lib crates?

Actually what am I doing, I can check

jieyouxu commented 1 day ago

I can't get past the building test helpers for this target cross-compiling from msvc host, not sure what's up with that.

workingjubilee commented 1 day ago

Huh.

cc @juntyr Can you make it any further?

jieyouxu commented 1 day ago

Also I note that wasm32-unknown-emscripten has no platform support docs and I have no clue what's needed to be able to run the tests. Because there's an open PR #131582 for this.

jieyouxu commented 1 day ago

In the open platform support docs PR this says

This target is not extensively tested in CI for the rust-lang/rust repository. It's recommended to test the wasm32-wasip1 target instead for WebAssembly compatibility.

... so I don't know, is this expected failure?

jieyouxu commented 1 day ago

Can you make it any further?

See https://github.com/rust-lang/rust/pull/131582#discussion_r1798638827 I was able to get past the build helpers stage by properly acquring the toolchain and making relevant env vars available to bootstrap. Didn't bother trying to diagnose past stage 1 std and tests because there's like a chain of failures.

Notably I see

warning: dropping unsupported crate type `dylib` for target `wasm32-unknown-emscripten`

warning: `std` (lib) generated 1 warning
hoodmane commented 15 hours ago

The failing link command includes:

"-o" "/some/long/path/a.wasm"

if we replace that with a.js, then it links as expected. But then it fails to run it at:

executing cd "/.../rust/build/x86_64-unknown-linux-gnu/test/ui/abi/extern/extern-pass-TwoU8s" && RUSTC="/.../rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" RUST_TEST_THREADS="20" "/.../rust/build/x86_64-unknown-linux-gnu/test/ui/abi/extern/extern-pass-TwoU8s/a.wasm"

We should invoke a.js with node.

hoodmane commented 15 hours ago

So I guess for starters we should do:

--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1643,7 +1643,10 @@ fn make_exe_name(&self) -> PathBuf {
         // double the length.
         let mut f = self.output_base_dir().join("a");
         // FIXME: This is using the host architecture exe suffix, not target!
-        if self.config.target.starts_with("wasm") {
+        if self.config.target.contains("emscripten") {
+            f = f.with_extra_extension("js");
+        }
+        else if self.config.target.starts_with("wasm") {
             f = f.with_extra_extension("wasm");
         } else if self.config.target.contains("spirv") {
             f = f.with_extra_extension("spv");
hoodmane commented 14 hours ago

Combined with setting the runner to node this fixes most of the failing tests:

--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -612,6 +612,9 @@ pub fn from_triple(triple: &str) -> Self {
         if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") {
             target.no_std = true;
         }
+        if triple.contains("emscripten") {
+            target.runner = Some("node".into());
+        }
         target
     }
 }
hoodmane commented 14 hours ago

The failures seem to be:

and tests/ui/issues/issue-12699.rs seems like it hangs? process-sigpipe sounds like an xfail.