Skip to content

ci: Use Clang on Windows #10890

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

Merged
merged 3 commits into from
Jun 13, 2025
Merged

Conversation

MangoPeachGrape
Copy link
Contributor

@MangoPeachGrape MangoPeachGrape commented Jun 2, 2025

I was running into linker warnings on Windows when linking a prebuilt wasmtime.lib against a debug version of my application:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library

But this didn't appear when using self-built wasmtime.lib, for either debug or release version of my app.

It turns out my build was built using Clang, while the prebuilt was using GCC.

Linker directives when built with GCC:

   Linker Directives
   -----------------
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:MSVCRT
   /DEFAULTLIB:OLDNAMES

Linker directives when built with Clang:

   Linker Directives
   -----------------
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:uuid.lib

Please note that I'm not a Windows expert, I don't know if /DEFAULTLIB:MSVCRT is the correct option, but it seems fine without it.

Feel free to let me know if this is not desired! (it might break something)

edit:
It seems to work the same in CI, now with Clang it only contains /DEFAULTLIB:uuid.lib.
Clang would need to be installed for the other targets in the case that this is something you want to go forward with.

@MangoPeachGrape MangoPeachGrape requested a review from a team as a code owner June 2, 2025 14:02
@MangoPeachGrape MangoPeachGrape requested review from abrown and removed request for a team June 2, 2025 14:02
@alexcrichton
Copy link
Member

Hm can you explain more about what's going on here? (if you can? I'm also no Windows expert...)

To confirm are you using the *-msvc targert or the *-gnu target (Rust target that is, not what we name our artifacts in CI). Given you're using wasmtime.lib I'm assuming you're using MSVC, but then I'm a bit baffled because GCC shouldn't be used on that target at all. Instead the default cl.exe should be used from Microsoft.

Additionally the C compiler that CC affects only changes how this file is compiled, so it's a pretty small change. So this might be a difference between cl.exe and clang.exe (which I could certainly believe) instead of with GCC?

Roughly to the best of my knowledge there are various CRT libraries on Windows that are ABI-incompatible which means that whatever is selected at compile-time must also be used at runtime which is what's being warned about here. That being said we might be using the ABI-stable bits that are the same across those libraries (I'm not sure). Our usage of the CRT is definitely quite small, it's pretty much just setjmp/longjmp...

@MangoPeachGrape
Copy link
Contributor Author

MangoPeachGrape commented Jun 2, 2025

To confirm are you using the *-msvc targert or the *-gnu target

Yes, x86_64-pc-windows-msvc.

but then I'm a bit baffled because GCC shouldn't be used on that target at all. Instead the default cl.exe should be used from Microsoft.

I saw this in the CI log of ci/build.release-artifacts.sh which lead me down this rabbit hole to believe it was using GCC:

 + mkdir -p target/c-api-build
+ cd target/c-api-build
+ cmake -G Ninja ../../crates/c-api -DCMAKE_BUILD_TYPE=Release -DWASMTIME_TARGET=x86_64-pc-windows-msvc -DCMAKE_INSTALL_PREFIX=../c-api-install -DCMAKE_INSTALL_LIBDIR=../c-api-install/lib
-- The C compiler identification is GNU 14.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/mingw64/bin/cc.exe - skipped

On my local machine it was this:

+ mkdir -p target/c-api-build
+ cd target/c-api-build
+ cmake -G Ninja ../../crates/c-api -DCMAKE_BUILD_TYPE=Release -DWASMTIME_TARGET=x86_64-pc-windows-msvc -DCMAKE_INSTALL_PREFIX=../c-api-install -DCMAKE_INSTALL_LIBDIR=../c-api-install/lib
-- The C compiler identification is Clang 20.1.0 with GNU-like command-line
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe - skipped

But yes, it makes much more sense that cl.exe would be been used and caused it

edit: Yes, the C compiler CMake chooses doesn't actually influence anything. So yes, clang vs cl.exe difference.

Now I'm wondering if there is an actual solution to this, other than compiling from source to both debug and release?

@alexcrichton
Copy link
Member

Ah ok yeah that makes sense, and agreed that the CMake-chosen compiler probably isn't doing anything. Although perhaps indicative that our MSVC tests are not testing what we think they are...

In any case, I have vague recollections of solving this in rust-lang/rust a long time ago, but it's now eluding me how exactly it was solved. Could you try turning on this flag perhaps and see if that helps? Skimming Microsoft's docs on this I don't find much that's illuminating...

@MangoPeachGrape
Copy link
Contributor Author

MangoPeachGrape commented Jun 2, 2025

Could you try turning on this flag perhaps and see if that helps?

diff --git i/crates/wasmtime/build.rs w/crates/wasmtime/build.rs
index 3b005414a..c2ba8f572 100644
--- i/crates/wasmtime/build.rs
+++ w/crates/wasmtime/build.rs
@@ -72,6 +72,7 @@ fn build_c_helpers() {
     use wasmtime_versioned_export_macros::versioned_suffix;

     let mut build = cc::Build::new();
+    build.static_crt(true);
     build.warnings(true);
     let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
     let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();

resulted in the same linker directives:

   Linker Directives
   -----------------
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:MSVCRT
   /DEFAULTLIB:OLDNAMES

Which is quite interesting...

edit: Now trying to link against it gives these warnings:

LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library

edit edit: This is actually the directives:

   Linker Directives
   -----------------
   /DEFAULTLIB:LIBCMT
   /DEFAULTLIB:OLDNAMES
   /EXPORT:wasmtime_resolve_vmctx_memory_ptr_34_0_0
   /EXPORT:wasmtime_set_vmctx_memory_34_0_0

   Linker Directives
   -----------------
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:MSVCRT
   /DEFAULTLIB:OLDNAMES

@alexcrichton
Copy link
Member

@jsturtevant could I perhaps tag you in to help out with this from the Windows side of things? (or perhaps if you could forward this along to others who may know as well?)

The basic question why cl.exe adds /DEFAULTLIB:MSVCRT but clang.exe does not. Is there a recommendation of what we're supposed to do in here how we distribute artifacts in CI? For example is it conventional to ship static libraries on Windows, and if so is there a convention for how such libraries are compiled (flag-wise). Overall I fear I'm not even knowledgable enough in this area to know what the right question is to ask, but that might be a starting point.

@MangoPeachGrape perhaps as a reference point as well, could you past the command/reproduction to generate the linker warning you're seeing as well?

@MangoPeachGrape
Copy link
Contributor Author

perhaps as a reference point as well, could you past the command/reproduction to generate the linker warning you're seeing as well?

Build an application that links with wasmtime.lib with any other runtime than /MD (in my case it was /MDd for the debug build of my app).

In VS2022 it's under "Project" -> "Properties" -> "C/C++" -> "Code Generation" -> "Runtime Library"

@jsturtevant
Copy link
Contributor

Build an application that links with wasmtime.lib with any other runtime than /MD (in my case it was /MDd for the debug build of my app).

This is a limitation of the Windows build and is documented (not very clearly) in https://learn.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=msvc-160#remarks

All modules passed to a given invocation of the linker must have been compiled with the same runtime library compiler option (/MD, /MT, /LD).

The way around this is to produce two artifacts, one with /MD and one with /MDd and the user would select the correct one according to the scenario.

For example is it conventional to ship static libraries on Windows, and if so is there a convention for how such libraries are compiled (flag-wise).

For this, it a bit more nuanced in the way the library ends up getting used due to the above. There is some guidance in https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170#what-problems-exist-if-an-application-uses-more-than-one-crt-version but it going to come down to alot of factors.

I did find this article that talks through this issue in detail: https://mygoldenchariot.blogspot.com/2006/07/link-warning-lnk4098-defaultlib-libcd.html

@alexcrichton
Copy link
Member

Hm ok I am still left with a question though of what's going on in rustc/llvm. Given the PR description it sounds like that the only difference is whether cl.exe or clang.exe compiles our helpers.c file, and when clang.exe does it there's no /DEFAULTLIB:MSVCRT but when compiled with cl.exe it shows up. Do you know why this directive is missing with clang.exe? Does that mean that it's ok to remove and is there a flag we can pass to cl.exe to remove it?

Also this makes me think that Rust's own usage of system libraries I guess doesn't fall into these categories? Assuming it's the C code causing this directive to show up then that means that Rust doesn't have /DEFAULTLIB:MSVCRT either. Does that mean that this is only an issue for C/C++ and not for Rust? If so, does that mean we could do a sort of manual audit that the symbols we use don't have different ABIs across these CRTs and say the clang.exe output is "more correct"?

@jsturtevant
Copy link
Contributor

Hm ok I am still left with a question though of what's going on in rustc/llvm. Given the PR description it sounds like that the only difference is whether cl.exe or clang.exe compiles our helpers.c file, and when clang.exe does it there's no /DEFAULTLIB:MSVCRT but when compiled with cl.exe it shows up.

Do you know why this directive is missing with clang.exe? Does that mean that it's ok to remove and is there a flag we can pass to cl.exe to remove it?

It seems clang uses the static libraries by default. So what I believe is happening is that by switching to clang the build has static link, and the @MangoPeachGrape is using clang for all the other libraries and so it all syncs up and there are no warnings.

is there a flag we can pass to cl.exe to remove it?

/NODEFAULTLIB
https://learn.microsoft.com/en-us/cpp/build/reference/nodefaultlib-ignore-libraries?view=msvc-170

The basic question why cl.exe adds /DEFAULTLIB:MSVCRT but clang.exe does not.

Going back to this question, generally MS recommends to not statically link unless required so the tooling sets that up by default. I found a few forum answers that said clang.exe was trying to make sure basic crt that works with helloworld https://discourse.llvm.org/t/change-default-config-of-clang-on-windows/54565

Also this makes me think that Rust's own usage of system libraries I guess doesn't fall into these categories? Assuming it's the C code causing this directive to show up then that means that Rust doesn't have /DEFAULTLIB:MSVCRT either. Does that mean that this is only an issue for C/C++ and not for Rust? If so, does that mean we could do a sort of manual audit that the symbols we use don't have different ABIs across these CRTs and say the clang.exe output is "more correct"?

This am I not sure.

@alexcrichton
Copy link
Member

Ok thanks for the info!

Could this perhaps try the /NODEFAULTLIB and see if that works @MangoPeachGrape? I'm still not really sure what the "true" fix for this is but that seems reasonable-ish in the meantime?

@MangoPeachGrape
Copy link
Contributor Author

Could this perhaps try the /NODEFAULTLIB

Doing this:

diff --git i/ci/build-release-artifacts.sh w/ci/build-release-artifacts.sh
index 93063334d..5582ea31e 100755
--- i/ci/build-release-artifacts.sh
+++ w/ci/build-release-artifacts.sh
@@ -66,6 +66,10 @@ else
   bin_flags="--features all-arch,component-model"
 fi

+if [[ "$build" = "x86_64-windows" ]]; then
+  export RUSTFLAGS="-C link-args=/NODEFAULTLIB:MSVCRT $RUSTFLAGS"
+fi
+
 cargo build --release $flags --target $target -p wasmtime-cli $bin_flags --features run

 mkdir -p target/c-api-build

results in a lot of linker unresolved external symbol errors, here's a snippet:

libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.10.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.1.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.08.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.07.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.04.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.01.rcgu.o) : error LNK2001: unresolved external symbol ceilf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.6.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.10.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.1.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.08.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.07.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.04.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.01.rcgu.o) : error LNK2001: unresolved external symbol floorf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.6.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.10.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.1.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.08.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.07.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.04.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.01.rcgu.o) : error LNK2001: unresolved external symbol floor␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.08.rcgu.o) : error LNK2019: unresolved external symbol fmodf referenced in function _ZN8wasmtime7runtime2vm8libcalls3raw11nearest_f3217h2c07c9b2a654e329E␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.07.rcgu.o) : error LNK2001: unresolved external symbol fmodf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.1.rcgu.o) : error LNK2001: unresolved external symbol fmodf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.6.rcgu.o) : error LNK2001: unresolved external symbol fmodf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.6.rcgu.o) : error LNK2001: unresolved external symbol fmod␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.08.rcgu.o) : error LNK2001: unresolved external symbol fmod␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.07.rcgu.o) : error LNK2001: unresolved external symbol fmod␍
          libtoml_edit-e004635c75cc9be5.rlib(toml_edit-e004635c75cc9be5.toml_edit.36c6dc07afff2a59-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol fmod␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.1.rcgu.o) : error LNK2001: unresolved external symbol fmod␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.6.rcgu.o) : error LNK2001: unresolved external symbol fmaf␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.08.rcgu.o) : error LNK2001: unresolved external symbol fmaf␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.07.rcgu.o) : error LNK2001: unresolved external symbol fmaf␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.15.rcgu.o) : error LNK2001: unresolved external symbol fmaf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.1.rcgu.o) : error LNK2001: unresolved external symbol fmaf␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.6.rcgu.o) : error LNK2001: unresolved external symbol fma␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.08.rcgu.o) : error LNK2001: unresolved external symbol fma␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.07.rcgu.o) : error LNK2001: unresolved external symbol fma␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.15.rcgu.o) : error LNK2001: unresolved external symbol fma␍
          libpulley_interpreter-520975c34d378a19.rlib(pulley_interpreter-520975c34d378a19.pulley_interpreter.7e281e267ea5c3f2-cgu.1.rcgu.o) : error LNK2001: unresolved external symbol fma␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.10.rcgu.o) : error LNK2019: unresolved external symbol abort referenced in function _ZN111_$LT$wasmtime..runtime..vm..sys..windows..vectored_exceptions..TrapHandler$u20$as$u20$core..ops..drop..Drop$GT$4drop17h33de1eb44ef366b0E␍
          libwasmtime-dcc024f25d9c2a0c.rlib(wasmtime-dcc024f25d9c2a0c.wasmtime.77c60893eb9138a3-cgu.14.rcgu.o) : error LNK2001: unresolved external symbol abort␍
          libwasmtime-dcc024f25d9c2a0c.rlib(242b1992def1ef0b-helpers.o) : error LNK2019: unresolved external symbol longjmp referenced in function wasmtime_longjmp_34_0_0␍
          libwasmtime-dcc024f25d9c2a0c.rlib(242b1992def1ef0b-helpers.o) : error LNK2019: unresolved external symbol _setjmp referenced in function wasmtime_setjmp_34_0_0␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.04.rcgu.o) : error LNK2019: unresolved external symbol truncf referenced in function _ZN105_$LT$cranelift_codegen..opts..IsleContext$u20$as$u20$cranelift_codegen..opts..generated_code..Context$GT$9f32_trunc17h0a3678211f87dfffE␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.01.rcgu.o) : error LNK2001: unresolved external symbol truncf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol truncf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.10.rcgu.o) : error LNK2001: unresolved external symbol truncf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.04.rcgu.o) : error LNK2019: unresolved external symbol rintf referenced in function _ZN105_$LT$cranelift_codegen..opts..IsleContext$u20$as$u20$cranelift_codegen..opts..generated_code..Context$GT$11f32_nearest17h074e629038a807b9E␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.01.rcgu.o) : error LNK2001: unresolved external symbol rintf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol rintf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.10.rcgu.o) : error LNK2001: unresolved external symbol rintf␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.04.rcgu.o) : error LNK2019: unresolved external symbol trunc referenced in function _ZN105_$LT$cranelift_codegen..opts..IsleContext$u20$as$u20$cranelift_codegen..opts..generated_code..Context$GT$9f64_trunc17h0741f8748d577813E␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.01.rcgu.o) : error LNK2001: unresolved external symbol trunc␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol trunc␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.10.rcgu.o) : error LNK2001: unresolved external symbol trunc␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.04.rcgu.o) : error LNK2019: unresolved external symbol rint referenced in function _ZN105_$LT$cranelift_codegen..opts..IsleContext$u20$as$u20$cranelift_codegen..opts..generated_code..Context$GT$11f64_nearest17h0272fa37bc73460fE␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.01.rcgu.o) : error LNK2001: unresolved external symbol rint␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.12.rcgu.o) : error LNK2001: unresolved external symbol rint␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.10.rcgu.o) : error LNK2001: unresolved external symbol rint␍
          libcranelift_codegen-55d5056c86592a5c.rlib(cranelift_codegen-55d5056c86592a5c.cranelift_codegen.88ab1d07c376c596-cgu.03.rcgu.o) : error LNK2019: unresolved external symbol powf referenced in function _ZN17cranelift_codegen3isa5s390x5lower4isle14generated_code27constructor_fcvt_to_uint_ub17hba3b6d76627e500bE␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(c2d906b55b9e1a32-cs.o) : error LNK2001: unresolved external symbol malloc␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(c2d906b55b9e1a32-cs.o) : error LNK2001: unresolved external symbol free␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(c2d906b55b9e1a32-cs.o) : error LNK2001: unresolved external symbol realloc␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(c2d906b55b9e1a32-cs.o) : error LNK2001: unresolved external symbol calloc␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(c2d906b55b9e1a32-cs.o) : error LNK2019: unresolved external symbol __imp___stdio_common_vsprintf referenced in function vsnprintf␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(9dd4d0e1d766cc31-M68KInstPrinter.o) : error LNK2001: unresolved external symbol __imp___stdio_common_vsprintf␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(0f29f8491c100b87-X86ATTInstPrinter.o) : error LNK2019: unresolved external symbol __imp_strncpy referenced in function printMemReference␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(fac81700a0ff139a-AArch64BaseInfo.o) : error LNK2001: unresolved external symbol __imp_strncpy␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(c2d906b55b9e1a32-cs.o) : error LNK2001: unresolved external symbol __imp_strncpy␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(fac81700a0ff139a-AArch64InstPrinter.o) : error LNK2001: unresolved external symbol __imp_strncpy␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(051c5673732e439a-SparcInstPrinter.o) : error LNK2001: unresolved external symbol __imp_strncpy␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(0f29f8491c100b87-X86IntelInstPrinter.o) : error
LNK2001: unresolved external symbol __imp_strncpy␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(c2d906b55b9e1a32-cs.o) : error LNK2019: unresolved external symbol strcpy referenced in function fill_insn␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(2cbd1a4609716e8f-TMS320C64xInstPrinter.o) : error LNK2001: unresolved external symbol strcpy␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(0923604640287a97-XCoreInstPrinter.o) : error LNK2001: unresolved external symbol strcpy␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(051c5673732e439a-SparcInstPrinter.o) : error LNK2001: unresolved external symbol strcmp␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(051c5673732e439a-SparcMapping.o) : error LNK2001: unresolved external symbol strcmp␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(2cbd1a4609716e8f-TMS320C64xMapping.o) : error LNK2001: unresolved external symbol strcmp␍
          libcapstone_sys-bfc0d82e973f98a4.rlib(0923604640287a97-XCoreMapping.o) : error LNK2001: unresolved external symbol strcmp␍

@alexcrichton
Copy link
Member

Hm ok well I have no idea what's going on. Maybe just use clang on the x86_64-windows builder, but leave everything else as the default?

@MangoPeachGrape MangoPeachGrape changed the title ci: Use Clang instead of GCC ci: Use Clang on Windows Jun 9, 2025
@alexcrichton
Copy link
Member

CI seems happy, yay! Can you double-check to confirm the binary artifacts of that build are as you expect?

@jsturtevant
Copy link
Contributor

I think using clang here might be a change from dynamically linking the CRT, to statically linking it by default. This could potentially affect other who are expecting it to be dynamically linked.

Would creating two published libraries, one statically linked CRT and one with a dynamically linked CRT also resolve the issue? I guess technically it would be 4, since you need the debug versions of them as well. This appears to be what other tools do as well google/filament#810

@alexcrichton
Copy link
Member

Personally I'd fear the amount of infrastructure required to handle the Windows-specific case of producing 4 static libraries when the only real difference between them is how one small C file is compiled amongst them. At that point I'd sort of rather prefer to push on removing the C from Wasmtime entirely to avoid the need to publish 4x more libraries for Windows.

But then again this is still under the murky assumption that for whatever reason /M{D,T}{,d} doesn't seem to apply to Rust-built code. I only really have guesses as to why that might be the case, and for all I know it's not actually valid to build a rust staticlib and expect that to link in C/C++ projects with any of the above flags...

@MangoPeachGrape
Copy link
Contributor Author

Can you double-check to confirm the binary artifacts of that build are as you expect?

Yes, dumpbin /directives wasmtime.lib gives:

   Linker Directives
   -----------------
   /DEFAULTLIB:uuid.lib
   /DEFAULTLIB:uuid.lib

and with my app it works linking against both the static and the dynamic lib in both debug and release (/MDd and /MD).

clang here might be a change from dynamically linking the CRT, to statically linking

dumpbin /symbols wasmtime.lib outputs snippets like these:

041 00000000 UNDEF  notype       External     | __imp_FreeLibrary
042 00000000 UNDEF  notype       External     | __imp_GetEnvironmentVariableA
043 00000000 UNDEF  notype       External     | malloc
044 00000000 UNDEF  notype       External     | __imp_LoadLibraryExA
045 00000000 UNDEF  notype       External     | free
046 00000000 UNDEF  notype       External     | __imp_GetProcAddress

which I would assume points to it still being linked dynamically, but I might be very wrong?

@jsturtevant
Copy link
Contributor

Personally I'd fear the amount of infrastructure required to handle the Windows-specific case of producing 4 static libraries when the only real difference between them is how one small C file is compiled amongst them. At that point I'd sort of rather prefer to push on removing the C from Wasmtime entirely to avoid the need to publish 4x more libraries for Windows.

makes sense

and with my app it works linking against both the static and the dynamic lib in both debug and release (/MDd and /MD).

interesting, I guess something else is going on then. I don't know the best way to detect if it is static/dynamic in a lib. I've only really ran into this executables.

@alexcrichton
Copy link
Member

Ok given that this is all working for @MangoPeachGrape I'm tempted to go ahead and merge this and consider other possible changes in future follow-ups. I hope to one day also remove the last bits of C from Wasmtime eventually too...

@MangoPeachGrape mind updating this PR though to leave a comment in the code itself for why clang is specifically selected? Other than that happy to flag to merge.

@alexcrichton alexcrichton added this pull request to the merge queue Jun 12, 2025
Merged via the queue into bytecodealliance:main with commit a792863 Jun 13, 2025
160 checks passed
@MangoPeachGrape MangoPeachGrape deleted the ci/clang branch June 16, 2025 20:17
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

Successfully merging this pull request may close these issues.

3 participants