Snippets icon indicating copy to clipboard operation
Snippets copied to clipboard

SDL version test should be done at runtime

Open rtrussell opened this issue 2 years ago • 10 comments

The latest version of SDL_stbimage.h includes some code conditional on the version of SDL, which is achieved as follows:

#if SDL_VERSION_ATLEAST(2, 0, 5)

Whilst this is fine when SDL2 is incorporated in a static build, it's problematical when an application is linked at runtime with a shared SDL2 library, such as SDL2.dll in Windows or libSDL2.so in Linux. This is because the conditional test is not checking the linked version of SDL2, but rather what headers happened to be used at compile time.

To ensure that such an application runs successfully with a shared version of SDL prior to 2.0.5 (unlikely, but possible with an old Windows or Linux installation) it would be necessary to perform the version check at run-time and use 'late binding' for the missing SDL_CreateRGBSurfaceWithFormatFrom() function to avoid a load-time error.

Indeed the version check would be superfluous, because getting the function address at run time with SDL_LoadObject() and SDL_LoadFuncition() would tell you whether it was available!

rtrussell avatar Jun 19 '22 10:06 rtrussell

No, this just means that if you build with SDL >= 2.0.5 you need SDL >= 2.0.5 at runtime as well, which I think is reasonable. Even LTS Linux distros have newer SDL versions nowadays, so I don't see much point in runtime loading SDL_CreateRGBSurfaceWithFormatFrom(). Probably the only platforms where not using SDL_CreateRGBSurfaceWithFormatFrom() are ones not supported by newer SDL versions (Mac PPC?)

DanielGibson avatar Jun 19 '22 16:06 DanielGibson

No, this just means that if you build with SDL >= 2.0.5 you need SDL >= 2.0.5 at runtime as well, which I think is reasonable.

I have no control over what version of SDL2 is used at runtime. As is common, I ship my app (in the case of Linux, anyway) without bundling SDL2, the user has to get it from the repository for his Linux distro (it's often pre-loaded). If the version in that repository is < 2.0.5, my app won't run at all - the loader will abort because of the missing SDL_CreateRGBSurfaceWithFormatFrom() function.

I think this applies in the case of the Raspberry Pi 2 (and probably Raspberry Pi 3 too). I don't think the version of SDL2 in their repositories has ever changed, or ever will. Those older Raspberry Pis are still available for purchase and are still supported, and it's an important platform for me..

I use the mechanism I described - late binding at run time - for the SDL_RenderFlush() function, which is only in SDL >= 2.0.10; if it's available the function is called, if not it isn't. If you won't do the same with SDL_stbimage.h I'll have to patch it myself, but I'd rather not have to do that.

rtrussell avatar Jun 19 '22 16:06 rtrussell

It is not realistic that a Linux user has SDL < 2.0.5 on their system. Even debian oldoldstable has 2.0.5. Writing SDL2 applications where every function that was introduced after 2.0.0 is loaded with SDL_LoadObject() is neither common nor fun.

DanielGibson avatar Jun 19 '22 16:06 DanielGibson

It is not realistic that a Linux user has SDL < 2.0.5 on their system.

Sorry, your reply crossed with my edit. I added that I think older Raspberry Pis may still use versions of SDL2 prior to 2.0.5. That's an unusual platform, because all the models are still available for purchase and are still supported.

rtrussell avatar Jun 19 '22 16:06 rtrussell

Don't all Raspberry Pis support the current (32bit) version of Raspberry Pi OS (formerly Raspbian)?

DanielGibson avatar Jun 19 '22 16:06 DanielGibson

Don't all Raspberry Pis support the current (32bit) version of Raspberry Pi OS (formerly Raspbian)?

Even if so, people don't update Raspberry Pis like they might a conventional Linux platform. There is no automatic version checking and prompting to upgrade, not least because it means burning a new SD card. Incompatibilities with things like video drivers (which recent releases of Raspberry Pi OS have broken for many people) mean it's common for ancient releases still to be in use. I can't say to my users that they must update their OS to run my app.

rtrussell avatar Jun 19 '22 16:06 rtrussell

Do you have any kind of numbers on that?

Even the old Raspbian based on Debian buster has SDL 2.0.9, I think. And upgrading doesn't only break things, but might also improve them, especially for drivers.

DanielGibson avatar Jun 19 '22 16:06 DanielGibson

Do you have any kind of numbers on that?

I'm afraid I don't. But I know that large numbers of old RPis are still in use, and I strongly suspect many of them will be running Jessie and Stretch. I know I wouldn't want to risk updating my OS if the machine is otherwise working perfectly.

Still, I understand your reluctance to make the change if the numbers are small, even though it's a simple and painless modification I guess I can wait until the complaints start coming in....

rtrussell avatar Jun 19 '22 17:06 rtrussell

Stretch should have 2.0.5 (at least debian stretch does)

running an unsupported OS without security updates doesn't seem very smart to me

DanielGibson avatar Jun 19 '22 17:06 DanielGibson

running an unsupported OS without security updates doesn't seem very smart to me

I know, but as I said the Raspberry Pi is a very untypical platform, in some ways more like an embedded system than a general-purpose computer, and often without internet access. And I can't rule out that some people may use my app in a turnkey system, booting straight into BBC BASIC with no user interaction.

But if it's the case that Stretch has 2.0.5 I am less worried than I was; my recollection is that my Raspberry Pi 3 doesn't have SDL_ComposeCustomBlendMode() but that needs 2.0.6.

rtrussell avatar Jun 19 '22 17:06 rtrussell