[Bug 1231820] New: wine-devel is missing archive files
https://bugzilla.suse.com/show_bug.cgi?id=1231820 Bug ID: 1231820 Summary: wine-devel is missing archive files Classification: openSUSE Product: openSUSE Tumbleweed Version: Current Hardware: x86-64 OS: openSUSE Tumbleweed Status: NEW Severity: Normal Priority: P5 - None Component: Development Assignee: screening-team-bugs@suse.de Reporter: aleithner@level101.at QA Contact: qa-bugs@suse.de Target Milestone: --- Found By: --- Blocker: --- With both wine-devel and wine-devel-32bit installed, it is currently only possible to compile Winelib DLLs (using winegcc) as 32-bit objects. The wine-devel package only installs archive files for PE binaries in /usr/lib64/wine/x86_64-windows, whereas the wine-devel-32bit package installs archive files for both PE binaries in /usr/lib/wine/i386-windows and for ELF binaries in /usr/lib/wine/i386-unix. Building wine from source on my machine yields archive files for 64-bit ELF and PE binaries (in lib64/x86_64-unix and lib64/i386-windows respectively) and for 32-bit PE binaries (in lib64/i386-windows), though 32-bit ELF binaries can be compiled and linked using the self-built winegcc. For context and reference, see the Wine Developer's mailing list thread [1] where I have asked about this originally. [1]: https://list.winehq.org/mailman3/hyperkitty/list/wine-devel@winehq.org/threa... -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1231820 https://bugzilla.suse.com/show_bug.cgi?id=1231820#c2 Aaron Puchert <aaronpuchert@alice-dsl.net> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |aaronpuchert@alice-dsl.net Status|NEW |CONFIRMED --- Comment #2 from Aaron Puchert <aaronpuchert@alice-dsl.net> --- This issue seems to break the build of wine-nine-standalone on x86_64, but not 32-bit x86. The build fails in the configuration phase, where it's trying to detect presence of dlopen (edited for readability): Command line: `winegcc [...]/testfile.c -o [...]/output.exe -m64 -D_FILE_OFFSET_BITS=64 -O0 -mwindows` -> 2 stderr: /usr/x86_64-suse-linux/bin/ld: cannot find -lshell32: No such file or directory /usr/x86_64-suse-linux/bin/ld: cannot find -lcomdlg32: No such file or directory /usr/x86_64-suse-linux/bin/ld: cannot find -lgdi32: No such file or directory /usr/x86_64-suse-linux/bin/ld: cannot find -ladvapi32: No such file or directory /usr/x86_64-suse-linux/bin/ld: cannot find -luser32: No such file or directory /usr/x86_64-suse-linux/bin/ld: cannot find -lwinecrt0: No such file or directory /usr/x86_64-suse-linux/bin/ld: cannot find -lkernel32: No such file or directory /usr/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 But I'm not sure if the libraries are missing, after all there are files that would resolve this in x86_64-windows. Let's try with a simple "int main() {}". When I add -L/usr/lib64/wine/x86_64-windows, I get the same errors that you got:
winegcc main.c -o output.exe -m64 -mwindows -L/usr/lib64/wine/x86_64-windows /usr/bin/ld: relocatable linking with relocations from format pe-x86-64 (/usr/lib64/wine/x86_64-windows/libuser32.a(user32_syms-000001f6.o)) to format elf64-x86-64 (tmp6742bbac/output-00000001.spec-00000001.o) is not supported winebuild: winegcc: /usr/bin/winebuild failed
However, when I instead set the environment variable LIBRARY_PATH=/usr/lib64/wine/x86_64-windows, I get $ winegcc main.c -o output.exe -m64 -mwindows /usr/x86_64-suse-linux/bin/ld: tmp6742b34d/output-00000001.spec.o: in function `__wine_spec_nt_header': (.data+0x28): undefined reference to `__wine_spec_exe_entry' collect2: error: ld returned 1 exit status winegcc: /usr/bin/gcc failed So it seems to have found the libraries and the format is matching. (My suspicion is that winegcc does some conversion under the hood, if we tell it about the libraries in the right way.) The error is now about a missing entry point. For regular ELF binaries the entry point would come from some object file passed into the linker. For now let's just rename "main" into "__wine_spec_exe_entry". This compiles. Adding some printf also works and even runs: $ ./output.exe 0050:err:winediag:nodrv_CreateWindow Application tried to create a window, but no driver could be loaded. 0050:err:winediag:nodrv_CreateWindow L"The explorer process failed to start." 0050:err:systray:initialize_systray Could not create tray window Hello World! The messages are because I run this outside of a graphical session. In a graphical session: $ ./output.exe 0080:fixme:wineusb:query_id Unhandled ID query type 0x5. wine: could not open working directory L"unix\\home\\aaron\\", starting in the Windows directory. Application could not be started, or no application associated with the specified file. ShellExecuteEx failed: File not found. Ok, this might be because we played around with the entry point. We're probably missing some setup. However, running it directly works again: $ wine64 output.exe.so 007c:fixme:wineusb:query_id Unhandled ID query type 0x5. Hello World! Now let's try some actual Windows functions, like MessageBox. The code is straightforward. But it doesn't quite build: /usr/x86_64-suse-linux/bin/ld: warning: user32_tail-00000001.o: missing .note.GNU-stack section implies executable stack /usr/x86_64-suse-linux/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker /usr/lib64/wine/x86_64-windows/libuser32.a(user32_syms-000001f6.o):(.idata$4+0x0): dangerous relocation: R_AMD64_IMAGEBASE with __ImageBase undefined /usr/lib64/wine/x86_64-windows/libuser32.a(user32_syms-000001f6.o):(.idata$5+0x0): dangerous relocation: R_AMD64_IMAGEBASE with __ImageBase undefined /usr/lib64/wine/x86_64-windows/libuser32.a(user32_syms-000001f6.o):(.idata$7+0x0): dangerous relocation: R_AMD64_IMAGEBASE with __ImageBase undefined /usr/lib64/wine/x86_64-windows/libuser32.a(user32_head-00000000.o):(.idata$2+0x0): dangerous relocation: R_AMD64_IMAGEBASE with __ImageBase undefined /usr/lib64/wine/x86_64-windows/libuser32.a(user32_head-00000000.o):(.idata$2+0xc): dangerous relocation: R_AMD64_IMAGEBASE with __ImageBase undefined /usr/lib64/wine/x86_64-windows/libuser32.a(user32_head-00000000.o):(.idata$2+0x10): dangerous relocation: R_AMD64_IMAGEBASE with __ImageBase undefined collect2: error: ld returned 1 exit status winegcc: /usr/bin/gcc failed The warnings are a bit smelly, but Ok. The build fails because of a missing symbol __ImageBase, which I think might be provided by the same object file that should also provide the entry point. Let's do something evil and add "__attribute__((used)) int __ImageBase;" to make it resolve. That makes it compile. Of course it doesn't run properly—it crashes instead, but that was expected. My suspicion is that there is an issue with the paths. The fact that it works on 32-bit, where we have everything in the more usual /usr/lib, versus our 64-bit setup in /usr/lib64, makes me think this might be a reason. However, I think the entry point and __ImageBase should come from some object file, and I can't find any in wine-devel. Looking through the build history, this have happened relatively recently, maybe in the last two months. Before that, wine-nine-standalone was building fine. (It's currently broken even on i586 because of a GCC issue, but that is fixed upstream and I encountered this while trying to update the package.) -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1231820 https://bugzilla.suse.com/show_bug.cgi?id=1231820#c3 --- Comment #3 from Alexander Leithner <aleithner@level101.at> --- (In reply to Aaron Puchert from comment #2)
But I'm not sure if the libraries are missing, after all there are files that would resolve this in x86_64-windows. Let's try with a simple "int main() {}". When I add -L/usr/lib64/wine/x86_64-windows, I get the same errors that you got:
...
However, when I instead set the environment variable LIBRARY_PATH=/usr/lib64/wine/x86_64-windows, I get
...
So it seems to have found the libraries and the format is matching. (My suspicion is that winegcc does some conversion under the hood, if we tell it about the libraries in the right way.)
I'm not sure if I'm understanding what you're trying to say/do here. I'll assume that your experiment produces a PE binary for the rest of my comment, as this is the way I read LD's output here. There are certain things we cannot do if we're building a Wine library as a PE binary as opposed to an ELF binary, see the replies to my question about this on the Wine developer mailing list. [1],[2] So, for what it's worth, the archives in question are in fact missing (at least their x86_64-unix variants) since presence of them in x86_64-windows has (should have) no implications when building ELF binaries.
My suspicion is that there is an issue with the paths. The fact that it works on 32-bit, where we have everything in the more usual /usr/lib, versus our 64-bit setup in /usr/lib64, makes me think this might be a reason.
This may be the case though I don't see why changing the paths when building Wine could lead it to not produce all files. When building Wine from source from the Wine project's Git repository, it generates the following folder structure: prefix/lib64/wine +- i386-windows +- x86_64-unix +- x86_64-windows but no prefix/lib folder and no i386-unix as is currently present in OpenSUSE's packages. Notably, with the above folder structure, Wine ELF DLLs can be built for both 32 and 64-bit although only x86_64-unix is present, as I've alluded to in this bug's description. I'm not well-versed enough in RPM spec writing to diagnose the issue with the build process further, though. Aside from paths the only notable difference I see in the current (failing) build logs of Wine on OBS [3],[4] to my local test is that I got the above folder structure after compiling wine with: --enable-archs=i386,x86_64 --enable-win64 in one go. [1]: https://list.winehq.org/mailman3/hyperkitty/list/wine-devel@winehq.org/messa... [2]: https://list.winehq.org/mailman3/hyperkitty/list/wine-devel@winehq.org/messa... [3]: https://build.opensuse.org/public/build/Emulators/openSUSE_Tumbleweed/i586/w... [4]: https://build.opensuse.org/public/build/Emulators/openSUSE_Tumbleweed/x86_64... -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1231820 https://bugzilla.suse.com/show_bug.cgi?id=1231820#c4 --- Comment #4 from Aaron Puchert <aaronpuchert@alice-dsl.net> --- (In reply to Alexander Leithner from comment #3)
I'm not sure if I'm understanding what you're trying to say/do here. I'll assume that your experiment produces a PE binary for the rest of my comment, as this is the way I read LD's output here.
No, it's whatever winegcc produces. You can see the flags, I didn't pass any special flags. Anyway, since you've asked: $ file output.exe output.exe: POSIX shell script, ASCII text executable But this is just a wrapper that in the end calls output.exe.so: $ file output.exe.so output.exe.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), static-pie linked, BuildID[sha1]=[...], with debug_info, not stripped So it's ELF and not PE. However, it's not a regular ELF binary: $ readelf --dynamic output.exe.so Dynamic section at offset 0x18e38 contains 21 entries: Tag Type Name/Value 0x0000000000000010 (SYMBOLIC) 0x0 0x0000000060009996 (Operating System specific: 60009996) 0x1000 0x000000000000000d (FINI) 0x15000 0x0000000060009994 (Operating System specific: 60009994) 0x18e28 0x0000000060009995 (Operating System specific: 60009995) 0x8 0x000000000000001a (FINI_ARRAY) 0x18e30 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) 0x0000000000000004 (HASH) 0x260 0x000000006ffffef5 (GNU_HASH) 0x2a0 0x0000000000000005 (STRTAB) 0x3e0 0x0000000000000006 (SYMTAB) 0x2d8 0x000000000000000a (STRSZ) 159 (bytes) 0x000000000000000b (SYMENT) 24 (bytes) 0x0000000000000003 (PLTGOT) 0x18fc8 0x0000000000000007 (RELA) 0x480 0x0000000000000008 (RELASZ) 216 (bytes) 0x0000000000000009 (RELAENT) 24 (bytes) 0x000000000000001e (FLAGS) SYMBOLIC BIND_NOW 0x000000006ffffffb (FLAGS_1) Flags: NOW 0x000000006ffffff9 (RELACOUNT) 5 0x0000000000000000 (NULL) 0x0 This is what winegcc is expected to produce according to my understanding. What am I trying to say? That I could make the missing library errors disappear, and not by telling winegcc to build a PE binary. (Which I wouldn't even know how to do.) This indicates that the libraries might not be missing.
My suspicion is that there is an issue with the paths. The fact that it works on 32-bit, where we have everything in the more usual /usr/lib, versus our 64-bit setup in /usr/lib64, makes me think this might be a reason.
This may be the case though I don't see why changing the paths when building Wine could lead it to not produce all files. When building Wine from source from the Wine project's Git repository, it generates the following folder structure:
prefix/lib64/wine +- i386-windows +- x86_64-unix +- x86_64-windows
I didn't try building it from source, but in the end that's also what the package does. You're right that e.g. x86_64-windows/advapi32.dll is a PE binary, but the linker doesn't complain about the library missing, nor about a mismatch between PE and ELF. Maybe there is some translation going on, after all this isn't a regular ELF binary and only works in Wine. So Wine might be able to load PE binaries just fine.
but no prefix/lib folder and no i386-unix as is currently present in OpenSUSE's packages. Notably, with the above folder structure, Wine ELF DLLs can be built for both 32 and 64-bit although only x86_64-unix is present, as I've alluded to in this bug's description.
I'm not well-versed enough in RPM spec writing to diagnose the issue with the build process further, though. Aside from paths the only notable difference I see in the current (failing) build logs of Wine on OBS [3],[4] to my local test is that I got the above folder structure after compiling wine with:
--enable-archs=i386,x86_64 --enable-win64
in one go.
For the default flavor (i.e. not wow64), we should have %configure \ --with-x \ --with-wayland \ --with-gstreamer \ --enable-win64 \ --verbose On x86_64. You can see what %configure expands to by running "rpm -E %configure". You can expand the entire spec file by running "rpmspec -P wine.spec". (But you might need the dependencies to be installed for that to work.) Anyway, the "--enable-archs=i386,x86_64" is an interesting difference. It seems to single-handedly explain that you have 32-bit libraries while the package does not. However, maybe we need "--enable-archs=x86_64". I could try that, but as you've noticed the build is failing. Somehow usage of the internal dependency generator broke, and that's way beyond my understanding. I've never seen that being used in another package, and I suspect it's not documented anywhere. -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1231820 https://bugzilla.suse.com/show_bug.cgi?id=1231820#c5 --- Comment #5 from Alexander Leithner <aleithner@level101.at> --- (In reply to Aaron Puchert from comment #4)
(In reply to Alexander Leithner from comment #3)
I'm not sure if I'm understanding what you're trying to say/do here. I'll assume that your experiment produces a PE binary for the rest of my comment, as this is the way I read LD's output here.
No, it's whatever winegcc produces. You can see the flags, I didn't pass any special flags. Anyway, since you've asked:
$ file output.exe output.exe: POSIX shell script, ASCII text executable
But this is just a wrapper that in the end calls output.exe.so:
$ file output.exe.so output.exe.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), static-pie linked, BuildID[sha1]=[...], with debug_info, not stripped
So it's ELF and not PE.
OK, so now we're on the same page. Sorry for the misunderstanding. In fact, I've tried compiling my project (a Wine DLL, not an executable, which will only yield an *.so) with LIBRARY_PATH set as you did and got the very same error messages about dangerous relocations relating to R_AMD64_IMAGEBASE. The point of this bug is not that the libraries (*.so, which AFAICT also come from wine-devel) are missing though, since those are available in the packages, but that the archive files (*.a) are missing, which would enable correct linking without any path shenanigans.
Anyway, the "--enable-archs=i386,x86_64" is an interesting difference. It seems to single-handedly explain that you have 32-bit libraries while the package does not. However, maybe we need "--enable-archs=x86_64".
The 32-bit archive files are present but the 64-bit ones are missing. (In fact, my source copy of Wine does not build the *.so files for 32-bit Unix even when using --enable-archs=i386,x86_64) I noticed in the build logs that both variants of the wine-devel package do not explicitly define which architecture to enable, so I guess that this could be causing the problem of missing 64-bit archive files? I will try to build Wine from source on my machine once again and I'll play around with the --enable-archs switch a little bit. Not sure when I'll have time for that though, but will report back with any results. -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1231820 https://bugzilla.suse.com/show_bug.cgi?id=1231820#c6 --- Comment #6 from Alexander Leithner <aleithner@level101.at> --- I've now finally found time to play a little with some of the ./configure parameters. For my findings, keep in mind that I'm testing this on a 64-bit openSUSE Tumbleweed machine (snapshot 20241129) with Wine from their Git at commit e28b587cd329a13795390597da97d4af7bbae3e3. Below I'll list configure command lines, the directory structure they're building and whether I was able to compile my Wine DLL as a 32-bit ELF and 64-bit ELF. Command line #0 is my original command line I've used initially before reporting this bug. (Note that I've built Wine with --prefix=<PREFIX> as an additional parameter to configure not listed here, where <PREFIX> is a path in my home directory.) Throughout my testing, I've tried to compile my Wine DLL using either of these commands: <PREFIX>/bin/winegcc -m32 --winebuild <PREFIX>/bin/winebuild -shared -o myproject.dll myproject_main.c myproject.spec <PREFIX>/bin/winegcc --winebuild <PREFIX>/bin/winebuild -shared -o myproject.dll myproject_main.c myproject.spec (0) ./configure --enable-archs=i386,x86_64 --enable-win64 Dirs: lib64/wine/i386-windows, lib64/wine/x86_64-unix, lib64/wine/x86_64-windows Builds 32-bit ELF: yes Builds 64-bit ELF: yes (1) ./configure --enable-archs=i386 Dirs: lib64/wine/i386-windows, lib64/wine/x86_64-unix Builds 32-bit ELF: yes Builds 64-bit ELF: yes (2) ./configure --build=i586-suse-linux --host=i586-suse-linux --enable-archs=i386 Dirs: lib/wine/i386-unix, lib/wine/i386-windows Builds 32-bit ELF: no Builds 34-bit ELF: yes (3) ./configure --build=i586-suse-linux --host=i586-suse-linux Dirs: lib/wine/i386-unix, lib/wine/i386-windows Builds 32-bit ELF: no Builds 64-bit ELF: yes (4) ./configure --build=i586-suse-linux --host=i586-suse-linux --enable-archs=i386,x86_64 Dirs: lib/wine/i386-unix, lib/wine/i386-windows, lib/wine/x86_64-windows Builds 32-bit ELF: no Builds 64-bit ELF: yes (5) ./configure --build=i586-suse-linux --host=i586-suse-linux --enable-archs=i386,x86_64 --enable-win64 Dirs: lib/wine/i386-unix, lib/wine/i386-windows, lib/wine/x86_64-windows Builds 32-bit ELF: no Builds 64-bit ELF: yes In environments produced by 2-5, compilation of my Wine DLL as a 32-bit ELF via the winegcc and winebuild produced by these builds failed with the same error message all the time: /usr/bin/ld: relocatable linking with relocations from format elf64-x86-64 (<PREFIX>/bin/../lib/wine/i386-unix/libwinecrt0.a(stub.o)) to format elf32-i386 (tmp674ef937/myproject-00000001.spec-00000001.o) is not supported winebuild: /usr/bin/ld failed with status 1 winegcc: <PREFIX>/bin/winebuild failed I find it very peculiar that the files produced as "x86_64-unix" support linking with 32-bit ELF DLLs but that the shared objects and archives explicitly labelled "i386-unix" do not (in fact, these shared objects are identified by file as "ELF 64-bit LSB shared object, x86-64", though I guess this is to be expected?). All in all, this experiment only showed that adding "--build=i586-suse-linux --host=i586-suse-linux" breaks things when compiling wine. Now I'm wondering if this actually is a bug with Wine's compilation process (Makefiles?) instead of openSUSE's but I'm afraid that any further diagnosis really is beyond me. -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1231820 https://bugzilla.suse.com/show_bug.cgi?id=1231820#c7 --- Comment #7 from Alexander Leithner <aleithner@level101.at> --- To add to my findings from earlier today, note that these apparently exhibit somehow the "inverse" of the problem reported in this bug: Whenever I build Wine using the command lines I've shared, I can build 64-bit Wine ELF DLL files, but am unable to build 32-bit ones. Using openSUSE's packages, I can only build 32-bit DLLs, but no 64-bit ones. I'm not at all sure what's going on here. -- You are receiving this mail because: You are on the CC list for the bug.
participants (1)
-
bugzilla_noreply@suse.com