Linking with gcc fails on Windows

02d87b5
Opened by Сухарик at 2020-08-12 16:22:35

The following code fails to link on both stable-gnu and nightly-gnu toolchains:

extern crate hound;

fn main() {
    let mut input = hound::WavReader::open("clarinet-d4.wav").unwrap();

    println!("Hello, world!");
}

The build fails with the following output: https://gist.github.com/suhr/2962444f16cfce13bdc7118fe658a33c. Note that hound is a pure Rust crate.

Strangely enough, a hello world without hound compiles just fine.

OS: Windows 7, toolchain: stable-gnu and nightly-gnu.

  1. This seems to be specific to your installation, it works fine for me (also Windows 7).

    It's weird that none of the files to be linked can be found, maybe gcc / ld doesn't like the cyrillic characters in the path? Although in that case you would expect the linking to never work.

    Rolf Karp at 2018-03-11 12:13:28

  2. I did some experiments and found something very strange: if you put the same code in C:\раст\msfz instead of C:\Users\Администратор\Общее\msfz, it compiles just fine! But in C:\Users\Администратор\Общее\msfz build still fails.

    Сухарик at 2018-03-11 13:06:32

  3. I wonder if it is related to making the linker command line long enough that it triggers the condition to pass in the linker command line by file. If so, it might be getting the encoding wrong.

    cc @alexcrichton

    Peter Atashian at 2018-03-11 13:22:46

  4. Indeed, I can reproduce this with C:\Users\Ааааббббввввгд\msfz, but not with C:\Users\Руст\msfz.

    Сухарик at 2018-03-11 13:36:39

  5. Ideal workaround: Use the pc-windows-msvc toolchain.

    Alternative workaround: Disable incremental compilation and set codegen units to 1, thereby shortening the linker command line length.

    Ideal solution: Figure out how to encode the linker command file such that MinGW interprets it as unicode.

    Temporary hack: Disable using linker command lines with the gnu linker when on Windows.

    Peter Atashian at 2018-03-11 14:40:30

  6. @suhr hm what version of gcc are you using? I'm unable to reproduce this locally, but maybe this got fixed in newer versions of gcc?

    Alex Crichton at 2018-03-12 20:21:34

  7. Both toolchains seem to use gcc 6.3.0.

    Сухарик at 2018-03-12 20:42:18

  8. Ah ok, I've got 7.2.0 in my environment, mind giving that a spin and see if it works?

    Alex Crichton at 2018-03-12 20:46:58

  9. How to update it on Windows?

    Сухарик at 2018-03-12 20:49:41

  10. Oh I personally use pacman locally but I think you can also download manually from the old sourceforge site

    Alex Crichton at 2018-03-12 21:04:26

  11. Well, this sounds somewhat complicated.

    Сухарик at 2018-03-12 21:15:51

  12. @suhr ok I tested locally and 6.3.0 works for me as well. What's the output if you execute gcc --version --verbose for you?

    Alex Crichton at 2018-03-12 21:23:46

  13. This is the gcc you get via rustup. I didn't do anything fancy, just used rustup.

    There's the output anyway:

    Using built-in specs.
    COLLECT_GCC=gcc
    Target: x86_64-w64-mingw32
    Configured with: ../../../src/gcc-6.3.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw630/x86_64-630-posix-seh-rt_v5-rev2/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw630/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw630/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw630/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw630/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev2, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw630/x86_64-630-posix-seh-rt_v5-rev2/mingw64/opt/include -I/c/mingw630/prerequisites/x86_64-zlib-static/include -I/c/mingw630/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw630/x86_64-630-posix-seh-rt_v5-rev2/mingw64/opt/include -I/c/mingw630/prerequisites/x86_64-zlib-static/include -I/c/mingw630/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw630/x86_64-630-posix-seh-rt_v5-rev2/mingw64/opt/include -I/c/mingw630/prerequisites/x86_64-zlib-static/include -I/c/mingw630/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw630/x86_64-630-posix-seh-rt_v5-rev2/mingw64/opt/lib -L/c/mingw630/prerequisites/x86_64-zlib-static/lib -L/c/mingw630/prerequisites/x86_64-w64-mingw32-static/lib '
    Thread model: posix
    gcc version 6.3.0 (x86_64-posix-seh-rev2, Built by MinGW-W64 project)
    COLLECT_GCC_OPTIONS='--version' '-v' '-mtune=core2' '-march=nocona'
     cc1 -quiet -v -iprefix C:/Users/Администратор/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/bin/../lib/gcc/x86_64-w64-mingw32/6.3.0/ -D_REENTRANT help-dummy -quiet -dumpbase help-dummy -mtune=core2 -march=nocona -auxbase help-dummy -version --version -o C:\Users\836D~1\AppData\Local\Temp\cc96Bt81.s
    gcc: error: CreateProcess: No such file or directory
    

    Сухарик at 2018-03-12 22:02:00

  14. Ah ok odd! In any case I tried a few more ways to reproduce this and have done a bit of digging. It look like unfortunately gcc basically doesn't support paths with unicode in them at all. Basically nothing I've done gets it fed into gcc and gets gcc to like it. So in that sense I think the sheer fact that there's non-ascii in any argument passed to gcc is going to cause problems?

    Alex Crichton at 2018-03-13 15:11:56

  15. With that in mind @suhr I think your options are:

    • Switch to using the MSVC target
    • Set RUSTUP_HOME and CARGO_HOME to be in a directory that only has ascii characters in PATH

    Alex Crichton at 2018-03-13 15:18:35

  16. Switch to using the MSVC target

    My experience with MSVC toolchain was unfortunate: it couldn't find link.exe even though I had Microsoft Visual C++ Build Tools 2017 installed. I used the Internet and found an opinion that msvc toolchain being broken is the normal state of things and if you don't use msvc you don't need msvc toolchain anyway.

    So I decided to use the GNU toolchain and ran into this bug.

    Сухарик at 2018-03-13 15:36:34

  17. Oh dear that also sounds bad! It's definitely our intention that the MSVC toolchain is automatically located and if it's not that's a bug on our end.

    It sounds like this is also a plausible bug for rustbuild to warn and/or refuse to install the MinGW target as a host in a path with non-ascii

    Alex Crichton at 2018-03-13 18:08:34

  18. @suhr you are probably missing some of registry entries or environment variables. MSVC installer itself is very buggy and there is little Rust can do about it. Sometimes you can fix it by doing full uninstall of Build Tools and installing it again. If it still does not help you can try Microsoft uninstaller but I only used it with full SDK so I don't know if it can fix Build Tools as well.

    For MinGW path issues response files could help but overall recommendation is to use short ASCII paths. Things could improve by using clang+lld on Windows but it's not quite ready yet, upcoming release 7.0 looks promising though.

    Mateusz Mikuła at 2018-07-02 16:47:54

  19. Insert my 15 cents.

    I tried to compile project with windows-gnu, but I had error simmilar to @suhr. It was because of my non-ASCII username Серега. So, I renamed it to ascii one and it works!

    Radio Guy at 2020-05-04 14:34:43

  20. Triage: Latest GCC and Binutils still don't handle Администратор in the path but this is not actionable by Rust. The same path works fine when using Clang+LLD as the linker.

    I think we should leave this issue open since we ship gcc.exe and ld.exe which don't handle it.

    Mateusz Mikuła at 2020-08-12 16:22:35