#837108 gcc-mingw-w64-i686's libgcc dll is not found by wine

#837108#5
Date:
2016-09-08 19:56:38 UTC
From:
To:
The default dll search path used by wine32 does not include the location
of the libgcc_s_sjlj-1.dll library supplied with gcc-mingw-w64-i686.

I can't say if it's wine, mingw, or both, which are wrong here. Wine's
dll directory, /usr/lib/i386-linux-gnu/wine/, seems reasonable, so I'm
filing it on mingw. But maybe it's no good idea to have
gcc-mingw-w64-i686 install files in the same directory. So we might need
to extend wine's dll path to add some suitable directory for other
packages to install dlls in.

My expectation is that if I compile a program using i686-w64-mingw32-gcc
or i686-w64-mingw32-g++, I should be able to run that executable using
wine. I've used to be able to do that, not sure at which package upgrade
it stopped working. Here's an example where this fails:

  #include <cstring>
  #include <stdio.h>

  int
  main(int argc, char **argv)
  {
    printf("foo\n");
    return 0;
  }

To reproduce, save into a file "hello.cxx", compile using

   i686-w64-mingw32-g++ hello.cxx

and run it using

   WINEDEBUG=err+all wine ./a.exe

Expected result is a line "foo" written to stdout. Instead, I get
the error

  err:module:import_dll Library libgcc_s_sjlj-1.dll (which is needed by L"Z:\\home\\nisse\\hack\\test\\a.exe") not found
  err:module:LdrInitializeThunk Main exe initialization for L"Z:\\home\\nisse\\hack\\test\\a.exe" failed, status c0000135

By strace (strace -f -e open wine a.exe), I see that wine attempts to open

  [pid 31177] open("/usr/lib/wine/../i386-linux-gnu/wine/./libgcc_s_sjlj-1.dll.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
  [pid 31177] open("/usr/lib/wine/../i386-linux-gnu/wine/./libgcc_s_sjlj-1.dll.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)

which seems ok, /usr/lib/i386-linux-gnu/wine/ exists and there
are a lot of dll files there. But not libgcc.

  $ apt-file search libgcc_s_sjlj
  gcc-mingw-w64-i686: /usr/lib/gcc/i686-w64-mingw32/4.9-posix/libgcc_s_sjlj-1.dll
  gcc-mingw-w64-i686: /usr/lib/gcc/i686-w64-mingw32/4.9-win32/libgcc_s_sjlj-1.dll

I have this package installed, and the files exist on my system, they
just aren't found by wine. Besides the different location, also note the
different file name, ".dll" vs ".dll.so".

The debian wine* packages I have installed are wine, wine32 and wine64,
all version 1.8.4-1.

The debian gcc-mingw* packages installed are gcc-mingw-w64,
gcc-mingw-w64-base, gcc-mingw-w64-i686, gcc-mingw-w64-x86-64, all
version 4.9.1-19+14.3.

I'm running this on an x86_64 machine running mostly debian stable,
but certain packages, including wine, installed from testing (apt-get
install -t testing wine).

Some curiosities:

  * Switching the order of the two includes, or deleting the include of
    <cstring.h>, makes this example work. It then prints out the message
    "foo", as expected. (The executable then no longer depends on the
    libgcc dll, I guess).

  * The strace output also shows that wine attempts to open
    "/usr/lib/wine/../i386-linux-gnu/wine/./%1.dll.so"
                                            ^^
Regards,
/Niels

#837108#10
Date:
2023-06-24 19:25:53 UTC
From:
To:
Hi Niels,

gcc-mingw-w64 ships different variants of libgcc, so it can’t just drop one
in a directory on the default Wine DLL path — Windows programs built with
gcc-mingw-w64 have to ensure that the appropriate DLLs are available
alongside them.

I don’t think it was ever possible to do that; even when gcc-mingw-w64 (or
gcc-mingw32) shipped a single version of libgcc, it wasn’t provided in a
directory Wine would use on its own. What *is* possible is that previous
versions of the compiler didn’t produce binaries needing libgcc in as many
cases, so you might end up with a binary which just works whereas now you
don’t.

Yes, .dll.so files are Wine-specific. The goal of the mingw-w64 packages is
to produce binaries which work on Windows (and incidentally, Wine).

Regards,

Stephen

#837108#17
Date:
2023-07-18 08:37:17 UTC
From:
To:
Stephen Kitt <skitt@debian.org> writes:

And to be clear, what's a good way to do that? Add the appropriate
mingw lib directory to WINEPATH? Is it fine to use a unix filename
there, it should it somehow de translated to a windows file name? (For
my use case, I'd prefer not copying the dll into the same directory as
the executable, even though that's probably the way to go if I were to
distribute executables to others).

Ah, that's possible, in particular, since I'm not sure if my earlier use
involved C++ at all.

Out of curiosity, is there a good reason for this?

Regards,
/Niels