diff --git a/CMakeLists.txt b/CMakeLists.txt index e591a011c1..aca82359ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -391,7 +391,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 055781dde3..c2107f84b1 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -1407,14 +1407,27 @@ macro(CheckKMSDRM) 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);