Reputation: 3442
I'm currently working on a project which required me to re-implement a Windows DLL as a Wine DLL (a Linux Shared Object). I want this DLL to be available to both 32-bit and 64-bit Wine processes and I'm building this on a 64-bit OpenSUSE Tumbleweed machine.
So far, I have only been able to compile my implementation as a 32-bit Winelib DLL using
winegcc -m32 -L/usr/lib/wine/i386-unix -shared -o myproject.dll myproject_main.c myproject.spec
Specifying -L/usr/lib/wine/i386-unix
was necessary because even winegcc
didn't pick up Wine's library path. The myproject.dll.so
works: 32-bit Wine processes can load the library and use it without problems.
Then, I have tried to compile it as a 64-bit object using
winegcc -L/usr/lib64/wine/x86_64-unix -shared -o myproject64.dll myproject_main.c myproject.spec
but to no avail. Linking fails with the message
/usr/lib64/gcc/x86_64-suse-linux/14/../../../../x86_64-suse-linux/bin/ld: cannot find -ladvapi32: No such file or directory
/usr/lib64/gcc/x86_64-suse-linux/14/../../../../x86_64-suse-linux/bin/ld: cannot find -luser32: No such file or directory
/usr/lib64/gcc/x86_64-suse-linux/14/../../../../x86_64-suse-linux/bin/ld: cannot find -lwinecrt0: No such file or directory
/usr/lib64/gcc/x86_64-suse-linux/14/../../../../x86_64-suse-linux/bin/ld: cannot find -lkernel32: No such file or directory
/usr/lib64/gcc/x86_64-suse-linux/14/../../../../x86_64-suse-linux/bin/ld: cannot find -lntdll: No such file or directory
collect2: error: ld returned 1 exit status
winegcc: /usr/bin/gcc failed
After checking the differences between /usr/lib/wine/i386-unix
and /usr/lib64/wine/x86_64-unix
, I found that the latter does not contain the necessary archive files (e.g. libkernel32.a
) at all, while the former does. I also have a /usr/lib64/wine/x86_64-windows
folder which contains those archive files, but they're PE binaries and can thus not be used for linking.
Indeed, OpenSUSE's packages do not populate archive files in x86_64-unix
, but only x86_64-windows
when being built. I've checked and Fedora's packages (at least the official ones from WineHQ) seem to have the opposite problem: I wasn't able to find the i386-unix
archive files, but the packages contain the x86_64-unix
ones.
I've already asked about this on the OpenSUSE forums where I was asked to go and ask at Wine's forums as "it doesn't seem to be a packaging issue." My post on WineHQ's forums has yet to get a reply, so I'm wondering if my approach is wrong: I feel like I should be able to compile my implementation as a 64-bit binary too. If that's how it's supposed to work, how would I go about compiling a 64-bit binary?
Upvotes: 0
Views: 153
Reputation: 3442
Compiling Winelib DLLs this way is indeed correct. The problem I've been experiencing stems from a problem with openSUSE's Wine packages which I've reported.
Until this is fixed, building Wine from source solves the problem. After having cloned the Wine repository, compiling can be done using
./configure --enable-archs=i386,x86_64 --enable-win64 --prefix=/path/to/builddir
make -j 4
make install
Note that --prefix=
specifies where the Wine executables etc. will be generated, in order to not overwrite any system Wine.
After compilation finishes, we can use our self-built winegcc to compile our Winelib DLLs like so:
# 32-bit DLL
/path/to/builddir/bin/winegcc -m32 --winebuild /path/to/builddir/bin/winebuild -shared -o myproject.dll myproject_main.c myproject.spec
# 64-bit DLL
/path/to/builddir/bin/winegcc --winebuild /path/to/builddir/bin/winebuild -shared -o myproject.dll myproject_main.c myproject.spec
Specifying --winebuild
is necessary if you have another (system-wide) version of winebuild
installed. This will make sure that our self-built winegcc
uses our self-built winebuild
.
In fact, specifying -L
for the location where winegcc
should look for library/archive files is superfluous and is another bug in openSUSE's packages (I've reported that one too).
Winelib DLLs built/linked with our self-built Wine are compatible with the system Wine version, as long as the system version is as old or newer than our self-built version. That said, always clone/checkout the oldest Wine version which your DLL shall be compatible with when building Wine from source.
Upvotes: 0