From e3a533f8380a19e9a957f18721bea5c354ff0cce Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 15:23:01 +0200 Subject: [PATCH 01/12] cmake: check we're not linking against a static c runtime without dlopen support --- cmake/sdlchecks.cmake | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 055781dde3..2b3cd93864 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -50,6 +50,7 @@ macro(FindLibraryAndSONAME _LIB) endmacro() macro(CheckDLOPEN) + set(dl_libs ) check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN_IN_LIBC) if(NOT HAVE_DLOPEN_IN_LIBC) cmake_push_check_state() @@ -57,11 +58,34 @@ macro(CheckDLOPEN) check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN_IN_LIBDL) cmake_pop_check_state() if(HAVE_DLOPEN_IN_LIBDL) + set(dl_libs dl) sdl_link_dependency(dl LIBS dl) endif() endif() if(HAVE_DLOPEN_IN_LIBC OR HAVE_DLOPEN_IN_LIBDL) - set(HAVE_DLOPEN TRUE) + set(working_dl TRUE) + check_linker_flag(C "-Wl,--fatal-warnings" LINKER_FATAL_WARNINGS) + if(LINKER_FATAL_WARNINGS) + # Check we're not linking against a static runtime which does not support dlopen + cmake_push_check_state() + string(APPEND CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--fatal-warnings") + list(APPEND CMAKE_REQUIRED_LIBRARIES ${dl_libs}) + check_c_source_compiles([===[ + #include + int main(int argc, char *argv[]) { + void *handle = dlopen("libc.so.6", RTLD_NOW | RTLD_GLOBAL); + void(*ptr_puts)(const char*)=dlsym(handle, "puts"); + dlclose(handle); + (void) argc; (void) argv; + return 0; + } + ]===] HAVE_LINKING_DLOPEN) + set(working_dl ${HAVE_LINKING_DLOPEN}) + cmake_pop_check_state() + endif() + if(working_dl) + set(HAVE_DLOPEN TRUE) + endif() endif() endmacro() From c2f830e5caaa248b20b64a4a5c1d02ce8eed2690 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 15:38:56 +0200 Subject: [PATCH 02/12] cmake: no loadso -> no hidapi-libusb --- cmake/sdlchecks.cmake | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 2b3cd93864..f7f45e238f 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -1302,11 +1302,16 @@ macro(CheckHIDAPI) if(HAVE_LIBUSB_H) set(HAVE_LIBUSB TRUE) if(SDL_HIDAPI_LIBUSB_SHARED) - target_get_dynamic_library(dynamic_libusb LibUSB::LibUSB) - if(dynamic_libusb) - set(HAVE_HIDAPI_LIBUSB_SHARED ON) - set(SDL_LIBUSB_DYNAMIC "\"${dynamic_libusb}\"") - sdl_link_dependency(hidapi INCLUDES $) + if(NOT HAVE_SDL_LOADSO) + message(WARNING "You must have SDL_LoadObject() support for dynamic hidapi libusb loading") + set(HAVE_HIDAPI_LIBUSB_SHARED OFF) + else() + target_get_dynamic_library(dynamic_libusb LibUSB::LibUSB) + if(dynamic_libusb) + set(HAVE_HIDAPI_LIBUSB_SHARED ON) + set(SDL_LIBUSB_DYNAMIC "\"${dynamic_libusb}\"") + sdl_link_dependency(hidapi INCLUDES $) + endif() endif() endif() if(NOT HAVE_HIDAPI_LIBUSB_SHARED) From 2402950fb4ce3f2b8af0422e707205cc07f4a430 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 16:27:10 +0200 Subject: [PATCH 03/12] cmake: no loadso -> no OpenXR --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e591a011c1..df62873546 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3623,7 +3623,7 @@ if(SDL_GPU) set(SDL_VIDEO_RENDER_GPU 1) set(HAVE_RENDER_GPU TRUE) endif() - if(SDL_GPU_OPENXR) + if(SDL_GPU_OPENXR AND HAVE_SDL_LOADSO) set(HAVE_GPU_OPENXR 1) endif() endif() From 11482e26254e016d3b73db36f1abb213c7cfa7b5 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 16:29:57 +0200 Subject: [PATCH 04/12] cmake: no loadso -> no Vulkan --- cmake/sdlchecks.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index f7f45e238f..d5a1251d29 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -955,7 +955,7 @@ macro(CheckOpenGLES) endmacro() macro(CheckVulkan) - if(SDL_VULKAN) + if(SDL_VULKAN AND HAVE_SDL_LOADSO) set(SDL_VIDEO_VULKAN 1) set(HAVE_VULKAN TRUE) if(SDL_RENDER_VULKAN) From fa67cd4a28b496b735b688de7981a8087fb2922a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 16:35:38 +0200 Subject: [PATCH 05/12] cmake: no loadso -> no OpenGL ES --- cmake/sdlchecks.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index d5a1251d29..a5193d2765 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -888,7 +888,7 @@ endmacro() # Requires: # - PkgCheckModules macro(CheckEGL) - if(SDL_OPENGL OR SDL_OPENGLES) + if((SDL_OPENGL OR SDL_OPENGLES) AND HAVE_SDL_LOADSO) cmake_push_check_state() find_package(OpenGL MODULE) list(APPEND CMAKE_REQUIRED_INCLUDES ${OPENGL_EGL_INCLUDE_DIRS}) @@ -1404,7 +1404,7 @@ macro(CheckKMSDRM) set(PC_LIBDRM_FOUND FALSE) set(PC_GBM_FOUND FALSE) endif() - if(PC_LIBDRM_FOUND AND PC_GBM_FOUND AND HAVE_OPENGL_EGL) + if(PC_LIBDRM_FOUND AND PC_GBM_FOUND AND SDL_VIDEO_OPENGL_EGL) set(HAVE_KMSDRM TRUE) set(HAVE_SDL_VIDEO TRUE) From dda4996cde6d1950eb2c25c90e3611882164e8d8 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 16:41:26 +0200 Subject: [PATCH 06/12] cmake: no loadso -> no steam storage --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df62873546..15bf24712f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2150,7 +2150,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) set(SDL_STORAGE_GENERIC 1) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/generic/*.c") - if(LINUX) + if(LINUX AND HAVE_SDL_LOADSO) set(SDL_STORAGE_STEAM 1) sdl_glob_sources( "${SDL3_SOURCE_DIR}/src/storage/steam/*.c" From 479b89e65e5fc6a557691b1c8490e1d54335191f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 16:50:12 +0200 Subject: [PATCH 07/12] cmake: no loadso -> no dbus and ibus --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15bf24712f..b3a9c77eba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1975,8 +1975,9 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) set(HAVE_INOTIFY 1) endif() + set(HAVE_DBUS FALSE) if(PKG_CONFIG_FOUND) - if(SDL_DBUS) + if(SDL_DBUS AND HAVE_SDL_LOADSO) pkg_search_module(DBUS dbus-1 dbus) if(DBUS_FOUND) set(HAVE_DBUS_DBUS_H TRUE) @@ -1987,7 +1988,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) endif() endif() - if(SDL_IBUS) + if(HAVE_DBUS) pkg_search_module(IBUS ibus-1.0 ibus) find_path(HAVE_SYS_INOTIFY_H NAMES sys/inotify.h) if(IBUS_FOUND AND HAVE_SYS_INOTIFY_H) @@ -1997,7 +1998,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) endif() endif() - if (HAVE_IBUS_IBUS_H OR HAVE_FCITX) + if (HAVE_IBUS OR HAVE_FCITX) set(SDL_USE_IME 1) endif() From 13db18d80d9adb2612a45a8e58aac27ea87f8a0f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 17:08:27 +0200 Subject: [PATCH 08/12] cmake: use HAVE_LIBUDEV_HEADER cache variable --- cmake/sdlchecks.cmake | 1 + test/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index a5193d2765..73f994c13a 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -1436,6 +1436,7 @@ macro(CheckKMSDRM) endmacro() macro(CheckLibUDev) + set(HAVE_LIBUDEV_H FALSE) if(SDL_LIBUDEV) check_include_file("libudev.h" HAVE_LIBUDEV_HEADER) if(HAVE_LIBUDEV_HEADER) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b6e7b724bf..5c5c4d2d27 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -258,8 +258,8 @@ if(LIBC_HAS_SIGNAL_H) add_definitions(-DHAVE_SIGNAL_H) endif() -check_include_file(libudev.h HAVE_LIBUDEV_H) -if(HAVE_LIBUDEV_H) +check_include_file(libudev.h HAVE_LIBUDEV_HEADER) +if(HAVE_LIBUDEV_HEADER) add_definitions(-DHAVE_LIBUDEV_H) endif() From d4f922754a129a18e9b8bbb9dcec775694ed229d Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 17:10:36 +0200 Subject: [PATCH 09/12] cmake: no loadso -> no liburing --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3a9c77eba..40c837a3be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2002,7 +2002,8 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) set(SDL_USE_IME 1) endif() - if(SDL_LIBURING) + set(HAVE_LIBURING_H FALSE) + if(SDL_LIBURING AND HAVE_SDL_LOADSO) pkg_search_module(LIBURING liburing-ffi) find_path(HAVE_LIBURING_H NAMES liburing.h) if(LIBURING_FOUND AND HAVE_LIBURING_H) From 56a28442f7e238abfda9157624a9617e57fd1013 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 18:09:18 +0200 Subject: [PATCH 10/12] cmake: wayland depends on egl --- cmake/sdlchecks.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 73f994c13a..f4534f12d9 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -671,7 +671,7 @@ endmacro() # - SDL_WAYLAND_SHARED opt # - HAVE_SDL_LOADSO opt macro(CheckWayland) - if(SDL_WAYLAND) + if(SDL_WAYLAND AND SDL_VIDEO_OPENGL_EGL) set(WAYLAND_PKG_CONFIG_SPEC "wayland-client>=1.18" wayland-egl wayland-cursor egl "xkbcommon>=0.5.0") if(PKG_CONFIG_FOUND) pkg_check_modules(PC_WAYLAND IMPORTED_TARGET ${WAYLAND_PKG_CONFIG_SPEC}) From 5c0260c4a77fcad343c5b5a77146a89d50934a72 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 20:55:53 +0200 Subject: [PATCH 11/12] cmake: add SDL_LIBURING_SHARED option --- CMakeLists.txt | 13 +-- cmake/sdlchecks.cmake | 35 ++++++++ include/build_config/SDL_build_config.h.cmake | 1 + src/io/io_uring/SDL_asyncio_liburing.c | 90 ++++++++++--------- 4 files changed, 88 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40c837a3be..5dee085dea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -324,6 +324,7 @@ set_option(SDL_LIBICONV "Prefer iconv() from libiconv, if available, set_option(SDL_GCC_ATOMICS "Use gcc builtin atomics" ${SDL_GCC_ATOMICS_DEFAULT}) dep_option(SDL_DBUS "Enable D-Bus support" ON "${UNIX_SYS}" OFF) dep_option(SDL_LIBURING "Enable liburing support" ON "${UNIX_SYS}" OFF) +dep_option(SDL_LIBURING_SHARED "Dynamically load liburing support" ON "SDL_LIBURING;SDL_DEPS_SHARED" OFF) dep_option(SDL_DISKAUDIO "Support the disk writer audio driver" ON "SDL_AUDIO" OFF) dep_option(SDL_DUMMYAUDIO "Support the dummy audio driver" ON "SDL_AUDIO" OFF) dep_option(SDL_DUMMYVIDEO "Use dummy video driver" ON "SDL_VIDEO" OFF) @@ -2002,16 +2003,8 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) set(SDL_USE_IME 1) endif() - set(HAVE_LIBURING_H FALSE) - if(SDL_LIBURING AND HAVE_SDL_LOADSO) - pkg_search_module(LIBURING liburing-ffi) - find_path(HAVE_LIBURING_H NAMES liburing.h) - if(LIBURING_FOUND AND HAVE_LIBURING_H) - set(HAVE_LIBURING_LIBURING_H TRUE) - sdl_include_directories(PRIVATE SYSTEM ${LIBURING_INCLUDE_DIRS}) - set(HAVE_LIBURING TRUE) - endif() - endif() + CheckLiburing() + if((FREEBSD OR NETBSD) AND NOT HAVE_INOTIFY) set(LibInotify_PKG_CONFIG_SPEC libinotify) pkg_check_modules(PC_LIBINOTIFY IMPORTED_TARGET ${LibInotify_PKG_CONFIG_SPEC}) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index f4534f12d9..57bd696afe 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -1515,3 +1515,38 @@ macro(CheckLibUnwind) endif() endif() endmacro() + +macro(CheckLiburing) + set(HAVE_LIBURING_H FALSE) + set(HAVE_LIBURING_SHARED OFF) + set(HAVE_LIBURING OFF) + if(SDL_LIBURING) + find_path(LIBURING_H_INCLUDE_PATH NAMES liburing.h) + if(LIBURING_H_INCLUDE_PATH) + if(SDL_LIBURING_SHARED) + if(NOT HAVE_SDL_LOADSO) + message(WARNING "You must have SDL_LoadObject() support for dynamic liburing support") + else() + FindLibraryAndSONAME(uring-ffi) + if(URING_FFI_LIB_SONAME) + sdl_include_directories(PRIVATE SYSTEM ${LIBURING_H_INCLUDE_PATH}) + set(SDL_LIBURING_DYNAMIC "\"${URING_FFI_LIB_SONAME}\"") + set(HAVE_LIBURING TRUE) + set(HAVE_LIBURING_SHARED TRUE) + endif() + endif() + endif() + if(NOT HAVE_LIBURING) + set(liburing_PKG_CONFIG_SPEC liburing) + pkg_check_modules(PC_LIBURING IMPORTED_TARGET ${liburing_PKG_CONFIG_SPEC}) + if(PC_LIBURING_FOUND) + set(HAVE_LIBURING TRUE) + sdl_link_dependency(liburing LIBS PkgConfig::PC_LIBURING PKG_CONFIG_PREFIX PC_LIBURING PKG_CONFIG_SPECS ${liburing_PKG_CONFIG_SPEC}) + endif() + endif() + endif() + if(HAVE_LIBURING) + set(HAVE_LIBURING_H TRUE) + endif() + endif() +endmacro() diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index e7d0b34f42..f11d18d152 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -218,6 +218,7 @@ #cmakedefine HAVE_LIBUDEV_H 1 #cmakedefine HAVE_LIBDECOR_H 1 #cmakedefine HAVE_LIBURING_H 1 +#cmakedefine SDL_LIBURING_DYNAMIC @SDL_LIBURING_DYNAMIC@ #cmakedefine HAVE_FRIBIDI_H 1 #cmakedefine SDL_FRIBIDI_DYNAMIC @SDL_FRIBIDI_DYNAMIC@ #cmakedefine HAVE_LIBTHAI_H 1 diff --git a/src/io/io_uring/SDL_asyncio_liburing.c b/src/io/io_uring/SDL_asyncio_liburing.c index a15218a1e3..31b2f76820 100644 --- a/src/io/io_uring/SDL_asyncio_liburing.c +++ b/src/io/io_uring/SDL_asyncio_liburing.c @@ -41,19 +41,17 @@ static bool (*CreateAsyncIOQueue)(SDL_AsyncIOQueue *queue); static void (*QuitAsyncIO)(void); static bool (*AsyncIOFromFile)(const char *file, const char *mode, SDL_AsyncIO *asyncio); -// we never link directly to liburing. -// (this says "-ffi" which sounds like a scripting language binding thing, but the non-ffi version -// is static-inline code we can't lookup with dlsym. This is by design.) -#define SDL_DRIVER_LIBURING_DYNAMIC "liburing-ffi.so.2" -static const char *liburing_library = SDL_DRIVER_LIBURING_DYNAMIC; +#ifdef SDL_LIBURING_DYNAMIC +static const char liburing_library[] = SDL_LIBURING_DYNAMIC; static void *liburing_handle = NULL; SDL_ELF_NOTE_DLOPEN( "io-io_uring", "Support for async IO through liburing", SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, - SDL_DRIVER_LIBURING_DYNAMIC + SDL_LIBURING_DYNAMIC ) +#endif #define SDL_LIBURING_FUNCS \ SDL_LIBURING_FUNC(int, io_uring_queue_init, (unsigned entries, struct io_uring *ring, unsigned flags)) \ @@ -65,8 +63,8 @@ SDL_ELF_NOTE_DLOPEN( SDL_LIBURING_FUNC(void, io_uring_prep_write,(struct io_uring_sqe *sqe, int fd, const void *buf, unsigned nbytes, __u64 offset)) \ SDL_LIBURING_FUNC(void, io_uring_prep_close, (struct io_uring_sqe *sqe, int fd)) \ SDL_LIBURING_FUNC(void, io_uring_prep_fsync, (struct io_uring_sqe *sqe, int fd, unsigned fsync_flags)) \ - SDL_LIBURING_FUNC(void, io_uring_prep_cancel, (struct io_uring_sqe *sqe, void *user_data, int flags)) \ - SDL_LIBURING_FUNC(void, io_uring_prep_timeout, (struct io_uring_sqe *sqe, struct __kernel_timespec *ts, unsigned count, unsigned flags)) \ + SDL_LIBURING_FUNC(void, io_uring_prep_cancel, (struct io_uring_sqe *sqe, const void *user_data, int flags)) \ + SDL_LIBURING_FUNC(void, io_uring_prep_timeout, (struct io_uring_sqe *sqe, const struct __kernel_timespec *ts, unsigned count, unsigned flags)) \ SDL_LIBURING_FUNC(void, io_uring_prep_nop, (struct io_uring_sqe *sqe)) \ SDL_LIBURING_FUNC(void, io_uring_sqe_set_data, (struct io_uring_sqe *sqe, void *data)) \ SDL_LIBURING_FUNC(void, io_uring_sqe_set_flags, (struct io_uring_sqe *sqe, unsigned flags)) \ @@ -103,21 +101,28 @@ typedef struct LibUringAsyncIOQueueData static void UnloadLibUringLibrary(void) { - if (liburing_library) { +#ifdef SDL_LIBURING_DYNAMIC + if (liburing_handle) { SDL_UnloadObject(liburing_handle); - liburing_library = NULL; + liburing_handle = NULL; } +#endif SDL_zero(liburing); } static bool LoadLibUringSyms(void) { +#ifdef SDL_LIBURING_DYNAMIC #define SDL_LIBURING_FUNC(ret, fn, args) { \ liburing.fn = (SDL_fntype_##fn) SDL_LoadFunction(liburing_handle, #fn); \ if (!liburing.fn) { \ return false; \ } \ } +#else + #define SDL_LIBURING_FUNC(ret, fn, args) \ + liburing.fn = fn; +#endif SDL_LIBURING_FUNCS #undef SDL_LIBURING_FUNC return true; @@ -130,43 +135,46 @@ static bool LoadLibUring(void) { bool result = true; +#ifdef SDL_LIBURING_DYNAMIC if (!liburing_handle) { liburing_handle = SDL_LoadObject(liburing_library); if (!liburing_handle) { - result = false; // Don't call SDL_SetError(): SDL_LoadObject already did. - } else { - result = LoadLibUringSyms(); - if (result) { - static const int needed_ops[] = { - IORING_OP_NOP, - IORING_OP_FSYNC, - IORING_OP_TIMEOUT, - IORING_OP_CLOSE, - IORING_OP_READ, - IORING_OP_WRITE, - IORING_OP_ASYNC_CANCEL - }; - - struct io_uring_probe *probe = liburing.io_uring_get_probe(); - if (!probe) { - result = false; - } else { - for (int i = 0; i < SDL_arraysize(needed_ops); i++) { - if (!io_uring_opcode_supported(probe, needed_ops[i])) { - result = false; - break; - } - } - liburing.io_uring_free_probe(probe); - } - } - - if (!result) { - UnloadLibUringLibrary(); - } + return false; } } +#endif + result = LoadLibUringSyms(); + if (result) { + static const int needed_ops[] = { + IORING_OP_NOP, + IORING_OP_FSYNC, + IORING_OP_TIMEOUT, + IORING_OP_CLOSE, + IORING_OP_READ, + IORING_OP_WRITE, + IORING_OP_ASYNC_CANCEL + }; + + struct io_uring_probe *probe = liburing.io_uring_get_probe(); + if (!probe) { + result = false; + } else { + for (int i = 0; i < SDL_arraysize(needed_ops); i++) { + if (!io_uring_opcode_supported(probe, needed_ops[i])) { + result = false; + break; + } + } + liburing.io_uring_free_probe(probe); + } + } + +#ifdef SDL_LIBURING_DYNAMIC + if (!result) { + UnloadLibUringLibrary(); + } +#endif return result; } From 1e9aa6af2b756987178576bab470bdc7994c1415 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 7 May 2026 16:21:41 +0200 Subject: [PATCH 12/12] cmake: add SDL_LIBUDEV_SHARED option --- CMakeLists.txt | 3 ++- cmake/sdlchecks.cmake | 20 ++++++++++++++++---- src/core/linux/SDL_udev.c | 18 +++++++++++++++--- src/core/linux/SDL_udev.h | 8 ++++---- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dee085dea..e332aaa82c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,7 +392,8 @@ dep_option(SDL_HIDAPI_LIBUSB "Use libusb for low level joystick drivers" O dep_option(SDL_HIDAPI_LIBUSB_SHARED "Dynamically load libusb support" ON "SDL_HIDAPI_LIBUSB;SDL_DEPS_SHARED" OFF) dep_option(SDL_HIDAPI_JOYSTICK "Use HIDAPI for low level joystick drivers" ON SDL_HIDAPI OFF) dep_option(SDL_VIRTUAL_JOYSTICK "Enable the virtual-joystick driver" ON SDL_HIDAPI OFF) -set_option(SDL_LIBUDEV "Enable libudev support" ON) +dep_option(SDL_LIBUDEV "Enable libudev support" ON ${UNIX_SYS} OFF) +dep_option(SDL_LIBUDEV_SHARED "Dynamically load libudev support" ON "SDL_LIBUDEV;SDL_DEPS_SHARED" OFF) set_option(SDL_ASAN "Use AddressSanitizer to detect memory errors" OFF) set_option(SDL_CCACHE "Use Ccache to speed up build" OFF) set_option(SDL_CLANG_TIDY "Run clang-tidy static analysis" OFF) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 57bd696afe..d04f8c905b 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -1437,14 +1437,26 @@ endmacro() macro(CheckLibUDev) set(HAVE_LIBUDEV_H FALSE) + set(HAVE_LIBUDEV FALSE) + set(HAVE_LIBUDEV_SHARED OFF) if(SDL_LIBUDEV) check_include_file("libudev.h" HAVE_LIBUDEV_HEADER) if(HAVE_LIBUDEV_HEADER) set(HAVE_LIBUDEV_H TRUE) - FindLibraryAndSONAME(udev) - if(UDEV_LIB_SONAME) - set(SDL_UDEV_DYNAMIC "\"${UDEV_LIB_SONAME}\"") - set(HAVE_LIBUDEV TRUE) + set(HAVE_LIBUDEV TRUE) + if(SDL_LIBUDEV_SHARED) + if(NOT HAVE_SDL_LOADSO) + message(WARNING "You must have SDL_LoadObject() support for dynamic libudev support") + else() + FindLibraryAndSONAME(udev) + if(UDEV_LIB_SONAME) + set(SDL_UDEV_DYNAMIC "\"${UDEV_LIB_SONAME}\"") + set(HAVE_LIBUDEV_SHARED TRUE) + endif() + endif() + endif() + if(NOT HAVE_LIBUDEV_SHARED) + sdl_link_dependency(udev PRIVATE LIBS udev) endif() endif() endif() diff --git a/src/core/linux/SDL_udev.c b/src/core/linux/SDL_udev.c index 73071410ae..35db562cdd 100644 --- a/src/core/linux/SDL_udev.c +++ b/src/core/linux/SDL_udev.c @@ -41,10 +41,8 @@ static const char *SDL_UDEV_LIBS[] = { SDL_UDEV_FALLBACK_LIBS }; #ifdef SDL_UDEV_DYNAMIC + #define SDL_UDEV_DLNOTE_LIBS SDL_UDEV_DYNAMIC, SDL_UDEV_FALLBACK_LIBS -#else -#define SDL_UDEV_DLNOTE_LIBS SDL_UDEV_FALLBACK_LIBS -#endif SDL_ELF_NOTE_DLOPEN( "events-udev", @@ -52,17 +50,21 @@ SDL_ELF_NOTE_DLOPEN( SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, SDL_UDEV_DLNOTE_LIBS ) +#endif static SDL_UDEV_PrivateData *_this = NULL; +#ifdef SDL_UDEV_DYNAMIC static bool SDL_UDEV_load_sym(const char *fn, void **addr); static bool SDL_UDEV_load_syms(void); +#endif static bool SDL_UDEV_hotplug_update_available(void); static void get_caps(struct udev_device *dev, struct udev_device *pdev, const char *attr, unsigned long *bitmask, size_t bitmask_len); static int guess_device_class(struct udev_device *dev); static int device_class(struct udev_device *dev); static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev); +#ifdef SDL_UDEV_DYNAMIC static bool SDL_UDEV_load_sym(const char *fn, void **addr) { *addr = SDL_LoadFunction(_this->udev_handle, fn); @@ -73,9 +75,12 @@ static bool SDL_UDEV_load_sym(const char *fn, void **addr) return true; } +#endif static bool SDL_UDEV_load_syms(void) { + +#ifdef SDL_UDEV_DYNAMIC /* cast funcs to char* first, to please GCC's strict aliasing rules. */ #define SDL_UDEV_SYM(x) \ if (!SDL_UDEV_load_sym(#x, (void **)(char *)&_this->syms.x)) \ @@ -83,6 +88,13 @@ static bool SDL_UDEV_load_syms(void) #define SDL_UDEV_SYM_OPTIONAL(x) \ SDL_UDEV_load_sym(#x, (void **)(char *)&_this->syms.x); +#else +#define SDL_UDEV_SYM(x) \ + _this->syms.x = x; + +#define SDL_UDEV_SYM_OPTIONAL(x) \ + _this->syms.x = x; +#endif SDL_UDEV_SYM(udev_device_get_action); SDL_UDEV_SYM(udev_device_get_devnode); diff --git a/src/core/linux/SDL_udev.h b/src/core/linux/SDL_udev.h index d4f737c07c..8fe273d15d 100644 --- a/src/core/linux/SDL_udev.h +++ b/src/core/linux/SDL_udev.h @@ -64,13 +64,13 @@ typedef struct SDL_UDEV_Symbols const char *(*udev_device_get_property_value)(struct udev_device *, const char *); const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr); struct udev_device *(*udev_device_new_from_syspath)(struct udev *, const char *); - void (*udev_device_unref)(struct udev_device *); + struct udev_device *(*udev_device_unref)(struct udev_device *); int (*udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *); int (*udev_enumerate_add_match_subsystem)(struct udev_enumerate *, const char *); struct udev_list_entry *(*udev_enumerate_get_list_entry)(struct udev_enumerate *); struct udev_enumerate *(*udev_enumerate_new)(struct udev *); int (*udev_enumerate_scan_devices)(struct udev_enumerate *); - void (*udev_enumerate_unref)(struct udev_enumerate *); + struct udev_enumerate *(*udev_enumerate_unref)(struct udev_enumerate *); const char *(*udev_list_entry_get_name)(struct udev_list_entry *); const char *(*udev_list_entry_get_value)(struct udev_list_entry *); struct udev_list_entry *(*udev_list_entry_get_next)(struct udev_list_entry *); @@ -79,9 +79,9 @@ typedef struct SDL_UDEV_Symbols int (*udev_monitor_get_fd)(struct udev_monitor *); struct udev_monitor *(*udev_monitor_new_from_netlink)(struct udev *, const char *); struct udev_device *(*udev_monitor_receive_device)(struct udev_monitor *); - void (*udev_monitor_unref)(struct udev_monitor *); + struct udev_monitor *(*udev_monitor_unref)(struct udev_monitor *); struct udev *(*udev_new)(void); - void (*udev_unref)(struct udev *); + struct udev *(*udev_unref)(struct udev *); struct udev_device *(*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum); dev_t (*udev_device_get_devnum)(struct udev_device *udev_device);