Compilation of SDL3 with importC failes (missing __builtin's)
Description
I've tried building the C based Simple Directmedia Layer (SDL) library (https://libsdl.org/) for version 3.2.0 using importC. It almost works, but is missing a few of the built-in functions otherwise for compiling the library.
These appear to be the built-ins: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
Short term suggested action are to add the built-ins to the importc.h or wherever otherwise appropriate. Users can otherwise do #define __builtin_mul_overflow(a,b,ret) 0 to otherwise get the importC compiler to work (The application appears to work, but the behavior would be broken for overflows).
Longer term suggested action, would be to use SDL3 as a test-suite for importC. Generally SDL3 is used by lots of game/multimedia developers, so if we can make the setup process as simple as including the header, that would be a big win for D for game developers.
Setup
Provided below is a test application and the command line I have used
- Tested on Ubuntu Linux 24.04
- Compiler: DMD64 D Compiler v2.111.0
- dmd app.d -L-lSDL3 -P-I/home/mike/Downloads/SDL3/include/SDL3/ sdl.c
Sample application
Sample application for testing purposes
// @file: app.d
import std.stdio;
import sdl;
void main(){
// Flags for subsystems we want to initialize
SDL_InitFlags flags = SDL_INIT_VIDEO | SDL_INIT_EVENTS;
// Initialize SDL
if(SDL_Init(flags)){
writeln("SDL was initialized");
}else{
writeln("Failed to initialize subsystems");
return;
}
// Create our window
SDL_Window* window = SDL_CreateWindow("DSDL3 window w/ manual binding - no dub packages",
320,240,0);
// 3 second delay (3000 ms)
SDL_Delay(3000);
// Destroy window
SDL_DestroyWindow(window);
writeln("Shutting down initialized subsystems");
SDL_Quit();
}
/// @file: sdl.c
//#define __builtin_mul_overflow(a,b,ret) 0
//#define __builtin_add_overflow(a,b,ret) 0
//#define __builtin_clz(x) 0
#include <SDL.h>
For the first 2 builtin functions, SDL3 uses them but with some compiler switch like SDL_HAS_BUILTIN:
#if SDL_HAS_BUILTIN(__builtin_mul_overflow)
/* This needs to be wrapped in an inline rather than being a direct #define,
* because __builtin_mul_overflow() is type-generic, but we want to be
* consistent about interpreting a and b as size_t. */
SDL_FORCE_INLINE bool SDL_size_mul_check_overflow_builtin(size_t a, size_t b, size_t *ret)
{
return (__builtin_mul_overflow(a, b, ret) == 0);
}
#define SDL_size_mul_check_overflow(a, b, ret) SDL_size_mul_check_overflow_builtin(a, b, ret)
#endif
and
#ifdef __has_builtin
#define SDL_HAS_BUILTIN(x) __has_builtin(x)
#else
#define SDL_HAS_BUILTIN(x) 0
#endif
So if __has_builtin is not defined, it will not be an issue.
Checked with the commit history,
__has_builtin is undefined by commit 23e2b3c94378848f80b4936c3f471c4ba844f9cc, but the undefining code is removed (so it's defined again) in commit b8b51f0db26367a732687e3c1b674f31ec19f2ff. So reverting commit of b8b51f0db26367a732687e3c1b674f31ec19f2ff might be a solution to the issue
(only the first 2 functions, the issue of the 3rd function is not fixed by that).
cc @ibuclaw