Rustc: Missing .dll.lib when cross compiling on Linux for Windows

Context: I'm trying to make this Meson unit test work when cross compiling for Windows on Linux: https://github.com/mesonbuild/meson/tree/master/test%20cases/rust/4%20polyglot.

Build logs:

[1/4] /usr/bin/x86_64-w64-mingw32-gcc -Iprog.exe.p -I. -I.. -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O0 -g -MD -MQ prog.exe.p/prog.c.obj -MF prog.exe.p/prog.c.obj.d -o prog.exe.p/prog.c.obj -c ../prog.c
[2/4] rustc --target x86_64-pc-windows-gnu -C linker=/usr/bin/x86_64-w64-mingw32-gcc --color=always -C debug-assertions=yes -C overflow-checks=no --crate-type cdylib -g --crate-name stuff --emit dep-info=stuff.d --emit link -o stuff.dll ../stuff.rs
[3/4] /home/xclaesse/.local/bin/meson --internal symbolextractor '/home/xclaesse/programmation/meson/test cases/rust/4 polyglot/builddir' stuff.dll stuff.dll.lib stuff.dll.p/stuff.dll.symbols --cross-host=windows
[4/4] /usr/bin/x86_64-w64-mingw32-gcc  -o prog.exe prog.exe.p/prog.c.obj -Wl,--allow-shlib-undefined stuff.dll.lib -Wl,--subsystem,console -Wl,--start-group -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -Wl,--end-group
FAILED: prog.exe 
/usr/bin/x86_64-w64-mingw32-gcc  -o prog.exe prog.exe.p/prog.c.obj -Wl,--allow-shlib-undefined stuff.dll.lib -Wl,--subsystem,console -Wl,--start-group -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -Wl,--end-group
/usr/bin/x86_64-w64-mingw32-ld: cannot find stuff.dll.lib: No such file or directory
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

When cross compiling, stuff.dll.lib is indeed not generated by the rustc command. The same project when built natively on Windows works, that command does generate stuff.dll.lib on Windows:

rustc -C linker=link --color=always -C debug-assertions=yes -C overflow-checks=no --crate-type cdylib -g --crate-name stuff --emit dep-info=stuff.d --emit link -o stuff.dll ../stuff.rs

The test.json says:

{
  "installed": [
    {"type": "exe", "file": "usr/bin/prog"},
    {"type": "pdb", "file": "usr/bin/prog"},
    {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
    {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
    {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.dll.lib"},
    {"type": "pdb", "file": "usr/bin/stuff"}
  ]
}

Looking at your logs you're building for the gcc platform, so it should indeed not have stuff.dll.lib as that's "platform": "msvc".

@chrisd hmmm, there is indeed something wrong there. I see that when Meson cross compile a normal C library there is a libfoo.dll.a file instead of foo.dll.lib, and rustc indeed created libstuff.dll.a in this case. That seems to be the link command that uses the wrong filename, probably a Meson bug then, thanks!

The naming is still a bit weird and I'm not sure that's intentional. As far as I understand conventions:

  • MSVC has foo.dll and foo.lib
  • GCC has libfoo.dll and libfoo.dll.a

With rustc and GCC linker (when cross compiling for Windows) I'm expecting to be following GCC convention, and thus -o libfoo.dll should produces libfoo.dll and libfoo.dll.a but instead of produces liblibfoo.dll.a (notice the repetition of the prefix).

With rustc and MSVC linker I'm expecting that passing -o foo.dll would produce foo.dll and foo.lib but instead of produces foo.dll.lib.

That means rustc made its own brand new convention? Is that intentional?