skeeto / w64devkit

Portable C and C++ Development Kit for x64 (and x86) Windows
The Unlicense
2.67k stars 185 forks source link

w64devkit-i686-1.18.0 dll linking in win10 64bit #51

Closed gwald closed 1 year ago

gwald commented 1 year ago

Hi :) This is a great compiler (w64devkit-i686-1.18.0) it runs great in windows XP and the generated executable are portable to newer 64bit windows!

And I know I'm probably pushing my luck, but thought I would ask, just in case.

I thought I would try the same compiler and same simple code and makefile, from winXP to win10 64bit, it compiles but fails to link with sdl2.dll (i686-w64-mingw32)

./SDL2.dll: file not recognized: file format not recognized collect2.exe: error: ld returned 1 exit status

Using the typical "-L. -lSDL2" works in XP, not in win10.

I tried linking with the dll.a files, but that gives a lot of SDL undefined references.

Looks like it compiles and links fine, I tested a simple printf("a %f \n",sin(1.5) ) program, and it works fine.

Which makes me think, it's a "just me" thing?

skeeto commented 1 year ago

I'm glad you've found this useful! I've also used w64devkit to develop, debug, and modify SDL2 applications on XP. It's neat how well it works.

SDL2 works fine with both 32-bit and 64-bit toolchains, and so a properly configured build will Just Work on every system from XP to 11. It sounds like you're mixing up 32-bit and 64-bit library and toolchain. Because I disable multilib support, you won't be able to use the 32-bit SDL2 from the 64-bit toolchain. The 32-bit builds you make on Windows 10 will still work on XP, and the host machine doesn't matter, so you don't actually need to build on XP to support it.

If the architecture of a library is unclear, use "objdump -a" to probe its type, which will report pei-i386, pei-x86-64, or sometimes unknown if it doesn't match your objdump's toolchain. Also try compiling with "gcc -v" to see if it may be picking up the wrong libraries from a place you didn't intend.

Manually using flags like "-lSDL2" is error prone. Proper builds are more complex than this, so you're bound to run into issues. Use sdl2-config to get the appropriate compiler flags for your target.

$ cc program.c $(sdl2-config --cflags --libs)

First put the SDL2 "bin/" directory on your PATH so that this script will be on available as a command. I suggest doing this in your .profile so that it's as good as "installed". (It will also put a copy of SDL2.dll on your PATH, which is convenient during development.) The config adds some other important options like -lmingw32 and -lSDL2main, and does so in the right order. More details:

SDL2 common mistakes and how to avoid them https://nullprogram.com/blog/2023/01/08/

Using sdl2-config like this, the above build command works correctly for every target supported by SDL2. You (mostly) don't need to do any kind of platform detection yourself. Caveat: It won't handle the EXE icon, which on Windows involves invoking windres and linking the icon.

Because w64devkit now provides a pkg-config, alternatively put the SDL2 "pkgconfig/" directory in your PKG_CONFIG_PATH — or even copy development SDL2 into w64devkit, where pkg-config already looks — then use pkg-config to configure your build:

$ eval cc program.c $(pkg-config sdl2 --cflags --libs)

You won't need to set your PATH in this case. The output is nearly identical to sdl2-config, but this works even when SDL2 is under a space-containing path, e.g. "Documents and Settings" on XP. (Though carefully note the eval, which is what makes this possible.)

Bonus: So your .profile environment settings work with both 32-bit and 64-bit toolchains, use "gcc -dumpmachine" to determine the correct SDL installation. For example, if you unpack the SDL2 development release in your home directory:

PATH="$HOME/sdl2/$(gcc -dumpmachine)/bin;$PATH"
PKG_CONFIG_PATH="$HOME/sdl2/$(gcc -dumpmachine)/bin;$PKG_CONFIG_PATH"

The first is for sdl2-config, and the second is for pkg-config.

If you install SDL2 into "w64devkit/" you'll want to merge the directories such that the "pkgconfig/" in w64devkit and SDL2 line up, i.e. merge on the architecture triple.

gwald commented 1 year ago

Thanks for the info! The scripts work great in the devkit console :+1: You're right, turns out I had the wrong sdl2.dll :/ WinXP support in win10 XP! :laughing:

Works perfectly, thank you! :) Subbed to your blog RSS :+1: And I'll pick your brain more there!