libsdl-org / SDL-1.2

Simple Directmedia Layer, 1.2 branch ... ***DEPRECATED***, please use https://github.com/libsdl-org/SDL for new projects!
https://libsdl.org
GNU Lesser General Public License v2.1
95 stars 81 forks source link

Windows 9X: SDL.DLL linked to MSVCRT.DLL:_strtoui64 #884

Open Fierelier opened 1 month ago

Fierelier commented 1 month ago

When I use SDL.DLL on Windows 98 Second Edition, I get this error:

The SDL.DLL file is linked to missing export MSVCRT.DLL:_strtoui64

I configure SDL like this:

CFLAGS="-march=i486 -O2 -D_WIN32_WINNT=0x0400 -DWINVER=0x0400" \
CXXFLAGS="-march=i486 -O2 -D_WIN32_WINNT=0x0400 -DWINVER=0x0400" \
./configure --host=i686-w64-mingw32 --prefix=/opt/sdl1.2

I tried commenting out line 118 and 119 in include/SDL_config_win32.h without success: https://github.com/libsdl-org/SDL-1.2/blob/0569bc61fe2ad18c8adbba72225d546336242999/include/SDL_config_win32.h#L118-L119

Is the issue with my compiler? I use i686-w64-mingw32-gcc (GCC) 13.2.0 on Gentoo i486.

ccawley2011 commented 1 month ago

Is that the only export that's missing? You can check by loading SDL.DLL into Dependency Walker from within Windows 98.

sezero commented 1 month ago

Looks like _strtoi? aren't present in win9x version of msvcrt.dll, even in latest vc6redist (e.g. from https://web.archive.org/web/20070329052640/http://support.microsoft.com/kb/259403)

Try commenting out those defines in the generated SDL_config.h

Fierelier commented 1 month ago

@ccawley2011 Just checked, those really seem to be the only two.

@sezero I ran the configure command and then edited include/SDL_config.h, commenting out the lines, and then ran make. No difference.

Fierelier commented 1 month ago

It is worth noting that _strtoi64 and _strtoui64 are mentioned in the changelog for 1.2.16: https://github.com/libsdl-org/SDL-1.2/blob/0569bc61fe2ad18c8adbba72225d546336242999/WhatsNew#L120

sezero commented 1 month ago

It is worth noting that _strtoi64 and _strtoui64 are mentioned in the changelog for 1.2.16:

I know

@sezero I ran the configure command and then edited include/SDL_config.h, commenting out the lines, and then ran make. No difference.

That doesn't make sense. I ran configure myself, commented out those two, built, and the generated dll doesn't link to _strtoi64 and _strtoui64 for me. Is yours really a clean build?

Fierelier commented 1 month ago

@sezero I made an entirely new clone of this git repo, did it again, same result.

From this https://github.com/libsdl-org/SDL-1.2/commit/a66cc7fe801066e05d3b4c86c63d120e21c954aa it looked like I might also have to undefine HAVE_STRTOLL and HAVE_STRTOULL, at a glance.

Made another fresh clone, configured, changed the config, did rm -rf /opt/sdl1.2, did make -j4 and make install. After I did that, it resulted in a binary of a different size, but I still get the error. Dependency Walker gives me the same thing still.

Sorry, I don't mean to cause confusion, I commented out these lines in include/SDL_config.h:

#define HAVE_STRTOLL 1
#define HAVE_STRTOULL 1
#define HAVE__STRTOI64 1
#define HAVE__STRTOUI64 1

Like so:

//#define HAVE_STRTOLL 1
//#define HAVE_STRTOULL 1
//#define HAVE__STRTOI64 1
//#define HAVE__STRTOUI64 1

...before running make.

sezero commented 1 month ago

I did exactly as you did, still can't reproduce. i686-w64-objdump -p SDL.dll | grep str gives only these for me: (only the relevant ones)

    68da8    1076  strchr
    68db2    1077  strcmp
    68dbc    1082  strerror
    68dc8    1084  strlen
    68dd2    1087  strncmp
    68ddc    1093  strstr
    68de6    1097  strtol
    68df0    1098  strtoul
    68e1a     666  _strdup
    68e24     669  _stricmp
    68e30     679  _strnicmp

This is with gcc 7.5 and binutils 2.29.1 and mingw-w64 8.0.3

Attaching my edited config and generated dll: 12.zip

Fierelier commented 1 month ago

@sezero I've tried your DLL and it works without issue. I will post my binary and config: sdl1.2.zip -- Our configs seem very similar, though.

I will have to sleep now, I'll try again tomorrow.

sezero commented 1 month ago

Our configs seem very similar, though.

The only difference are HAVE_NANOSLEEP (yours enabled, mine not) and SDL_HERMES_BLITTERS (mine enabled, yours not), both irrelevant to the actual issue.

At this point, all I can think of is maybe your mingw-w64 version is internally using _strtoi64 and _strtoui64 and leaking into the dll???

Hm, can you try, after configuring and editing the generated SDL_config.h, edit the generated Makefile and append -D__USE_MINGW_ANSI_STDIO=0 to your EXTRA_CFLAGS ? (Or, you can add it to your custom CFLAGS you showed above.)

EDIT: Forgot to note: Appending -Wl,-Map,SDL.map to EXTRA_LDFLAGS in generated Makefile and investigating the generated SDL.map can also help understanding this.

Fierelier commented 1 month ago

@sezero I added -D__USE_MINGW_ANSI_STDIO=0 to my CFLAGS and CXXFLAGS, that indeed fixed the issue! :) -- Such a nice thing to wake up to, after banging my head on this yesterday, thank you so much!

Do you think this is worth bringing up in the mingw-w64 project as an issue?


Here is my final script that cross-compiles SDL 1.2 for W9X:

CFLAGS="-march=i486 -O2 -D_WIN32_WINNT=0x0400 -DWINVER=0x0400 -D__USE_MINGW_ANSI_STDIO=0" \
CXXFLAGS="-march=i486 -O2 -D_WIN32_WINNT=0x0400 -DWINVER=0x0400 -D__USE_MINGW_ANSI_STDIO=0" \
./configure --host=i686-w64-mingw32 --prefix=/opt/sdl1.2
sed -i -e 's/#define HAVE_STRTOLL 1/\/\/#define HAVE_STRTOLL 1/g' "include/SDL_config.h"
sed -i -e 's/#define HAVE_STRTOULL 1/\/\/#define HAVE_STRTOULL 1/g' "include/SDL_config.h"
sed -i -e 's/#define HAVE__STRTOI64 1/\/\/#define HAVE__STRTOI64 1/g' "include/SDL_config.h"
sed -i -e 's/#define HAVE__STRTOUI64 1/\/\/#define HAVE__STRTOUI64 1/g' "include/SDL_config.h"
make -j4
make install

About HAVE__STRTOI64 and HAVE__STRTOUI64, would it make sense to automatically undefine those, if _WIN32_WINNT is less than 0x0501? They both seemed available for me on XP SP3.

If that suggestion makes sense, I could also test a 2000 SP4, to see if the breaking point is < 0x5000 (or 0x500004, if that is a thing?) instead.

sezero commented 1 month ago

@sezero I added -D__USE_MINGW_ANSI_STDIO=0 to my CFLAGS and CXXFLAGS, that indeed fixed the issue! :) -- Such a nice thing to wake up to, after banging my head on this yesterday, thank you so much!

OK, great!

About HAVE__STRTOI64 and HAVE__STRTOUI64, would it make sense to automatically undefine those, if _WIN32_WINNT is less than 0x0501? They both seemed available for me on XP SP3.

I may actually do that, yes

If that suggestion makes sense, I could also test a 2000 SP4, to see if the breaking point is < 0x5000 (or 0x500004, if that is a thing?) instead.

A test would be welcome (I don't have immediate access to w2k versions of msvcrt.dll)

P.S.: I am surprised that a mingw-w64 built SDL dll worked under w9x. I'd have suggested using original old mingw.org for that.

Fierelier commented 1 month ago

@sezero Those functions are available in W2K SP4 :)

P.S.: I am surprised that a mingw-w64 built SDL dll worked under w9x. I'd have suggested using original old mingw.org for that.

Huh! I'll keep that in mind should issues crop up in the future. Thanks again.

ccawley2011 commented 1 month ago

For what it's worth, I created a patch for mingw-w64 a while ago that allows the use of strtoll/strtoull/_strtoi64/_strtoui64 on all Windows versions that might help here: 0002-strtoi64-strtoui64-fallback.patch

sezero commented 1 month ago

About HAVE__STRTOI64 and HAVE__STRTOUI64, would it make sense to automatically undefine those, if _WIN32_WINNT is less than 0x0501? They both seemed available for me on XP SP3.

I may actually do that, yes

@sezero Those functions are available in W2K SP4 :)

OK looking at it, this can be really hairy at configuration level. Leaving things as is for now, but leaving this ticket open too.

FWIW, here is my own SDL.dll I've been using which is built using against old mingw.org headers and runtime using gcc-3.4.5: 1.zip