Skip to content

Commit 8fc87a7

Browse files
committed
Dynamically load libudev in linux-hidraw backend
Signed-off-by: falkTX <falktx@falktx.com>
1 parent 657b9fa commit 8fc87a7

3 files changed

Lines changed: 128 additions & 5 deletions

File tree

linux/CMakeLists.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ target_link_libraries(hidapi_hidraw PUBLIC hidapi_include)
88

99
find_package(Threads REQUIRED)
1010

11-
include(FindPkgConfig)
12-
pkg_check_modules(libudev REQUIRED IMPORTED_TARGET libudev)
13-
14-
target_link_libraries(hidapi_hidraw PRIVATE PkgConfig::libudev Threads::Threads)
11+
target_link_libraries(hidapi_hidraw PRIVATE Threads::Threads dl)
1512

1613
set_target_properties(hidapi_hidraw
1714
PROPERTIES

linux/hid.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
#include <linux/hidraw.h>
4141
#include <linux/version.h>
4242
#include <linux/input.h>
43-
#include <libudev.h>
43+
44+
/* falkTX: replaced by local file for dynamic loading */
45+
#include "libudev.c"
4446

4547
#include "hidapi.h"
4648

linux/libudev.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/* SPDX-FileCopyrightText: 2026 Filipe Coelho <falktx@falktx.com> */
2+
/* SPDX-License-Identifier: LGPL-2.1-or-later */
3+
4+
#include <dlfcn.h>
5+
#include <stdarg.h>
6+
#include <stddef.h>
7+
#include <sys/types.h>
8+
9+
#define C(FN) \
10+
static typeof(FN)* FN; \
11+
if (FN == NULL) { \
12+
void *realfn = dlsym(NULL, #FN); \
13+
FN = *(typeof(FN)*)&realfn; \
14+
}
15+
16+
#define udev_list_entry_foreach(varname, front) \
17+
for (varname = front; varname != NULL; varname = udev_list_entry_get_next(varname))
18+
19+
struct udev *udev_new(void)
20+
{
21+
static void* _lib;
22+
if (_lib == NULL)
23+
{
24+
_lib = dlopen("libudev.so.1", RTLD_NOW | RTLD_GLOBAL);
25+
if (_lib == NULL)
26+
return NULL;
27+
}
28+
29+
C(udev_new);
30+
return udev_new();
31+
}
32+
33+
struct udev *udev_unref(struct udev *udev)
34+
{
35+
C(udev_unref);
36+
return udev_unref(udev);
37+
}
38+
39+
struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
40+
{
41+
C(udev_device_new_from_devnum);
42+
return udev_device_new_from_devnum(udev, type, devnum);
43+
}
44+
45+
struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)
46+
{
47+
C(udev_device_new_from_syspath);
48+
return udev_device_new_from_syspath(udev, syspath);
49+
}
50+
51+
struct udev_device *udev_device_unref(struct udev_device *udev_device)
52+
{
53+
C(udev_device_unref);
54+
return udev_device_unref(udev_device);
55+
}
56+
57+
struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device,
58+
const char *subsystem, const char *devtype)
59+
{
60+
C(udev_device_get_parent_with_subsystem_devtype);
61+
return udev_device_get_parent_with_subsystem_devtype(udev_device, subsystem, devtype);
62+
}
63+
64+
const char* udev_device_get_syspath(struct udev_device *udev_device)
65+
{
66+
C(udev_device_get_syspath);
67+
return udev_device_get_syspath(udev_device);
68+
}
69+
70+
const char* udev_device_get_devnode(struct udev_device *udev_device)
71+
{
72+
C(udev_device_get_devnode);
73+
return udev_device_get_devnode(udev_device);
74+
}
75+
76+
const char* udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
77+
{
78+
C(udev_device_get_sysattr_value);
79+
return udev_device_get_sysattr_value(udev_device, sysattr);
80+
}
81+
82+
struct udev_enumerate *udev_enumerate_new(struct udev *udev)
83+
{
84+
C(udev_enumerate_new);
85+
return udev_enumerate_new(udev);
86+
}
87+
88+
struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate)
89+
{
90+
C(udev_enumerate_unref);
91+
return udev_enumerate_unref(udev_enumerate);
92+
}
93+
94+
int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
95+
{
96+
C(udev_enumerate_add_match_subsystem);
97+
return udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
98+
}
99+
100+
int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
101+
{
102+
C(udev_enumerate_scan_devices);
103+
return udev_enumerate_scan_devices(udev_enumerate);
104+
}
105+
106+
struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)
107+
{
108+
C(udev_enumerate_get_list_entry);
109+
return udev_enumerate_get_list_entry(udev_enumerate);
110+
}
111+
112+
struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry)
113+
{
114+
C(udev_list_entry_get_next);
115+
return udev_list_entry_get_next(list_entry);
116+
}
117+
118+
const char* udev_list_entry_get_name(struct udev_list_entry *list_entry)
119+
{
120+
C(udev_list_entry_get_name);
121+
return udev_list_entry_get_name(list_entry);
122+
}
123+
124+
#undef C

0 commit comments

Comments
 (0)