Skip to content

Dynamically load libudev in linux-hidraw backend - #788

Open
falkTX wants to merge 5 commits into
libusb:masterfrom
falkTX:linux-dynamic-libudev
Open

Dynamically load libudev in linux-hidraw backend#788
falkTX wants to merge 5 commits into
libusb:masterfrom
falkTX:linux-dynamic-libudev

Conversation

@falkTX

@falkTX falkTX commented Apr 24, 2026

Copy link
Copy Markdown

This PR removes the direct build and link dependency on libudev from the Linux hidraw backend. The backend now loads libudev.so.1 at runtime, so applications that link hidapi do not inherit a direct libudev dependency. Systems using the hidraw backend still need the libudev runtime library.

Implementation

  • Load libudev with a scoped RTLD_NOW | RTLD_LOCAL handle.
  • Resolve the exact libudev entry points used by hidapi and report missing-library or missing-symbol failures through hid_error().
  • Clear all resolved function pointers and close the handle on partial initialization failure and during hid_exit().
  • Remove the included LGPL loader source and the libudev development/pkg-config dependency.
  • Propagate the platform dynamic-loader library through CMake, Autotools, the manual Makefile, pkg-config, and installed static CMake exports.
  • Update Linux documentation and CI to install runtime-only packages (libudev1 on Ubuntu and eudev-libs on Alpine).
  • Add shared/static lifecycle tests for reloads, partial symbol-resolution failures, recovery, and balanced dlopen/dlclose cleanup.

Validation

  • Strict-warning shared and static CMake builds and CTests.
  • Shared ASAN CMake build and CTests.
  • Full CMake build with both Linux backends.
  • Fresh Autotools bootstrap/configure/build and distribution generation.
  • Manual Makefile build.
  • Installed static CMake consumer with libudev pkg-config metadata unavailable.

Assisted-by: codex:gpt-5.6-sol

@mcuee mcuee added the hidraw Related to Linux/hidraw backend label Apr 24, 2026
@mcuee

mcuee commented Apr 24, 2026

Copy link
Copy Markdown
Member

The build failed under Ubuntu and Arch Linux.

@falkTX
falkTX force-pushed the linux-dynamic-libudev branch 2 times, most recently from b86c642 to de4b582 Compare April 24, 2026 10:46
@falkTX

falkTX commented Apr 24, 2026

Copy link
Copy Markdown
Author

The build failed under Ubuntu and Arch Linux.

Related to more strict warnings, likely fixed now.

Signed-off-by: falkTX <falktx@falktx.com>
@mcuee

mcuee commented Apr 24, 2026

Copy link
Copy Markdown
Member

The build failed under Ubuntu and Arch Linux.

Related to more strict warnings, likely fixed now.

Not yet...

@falkTX
falkTX force-pushed the linux-dynamic-libudev branch from de4b582 to 8fc87a7 Compare April 24, 2026 12:25
@falkTX

falkTX commented Apr 24, 2026

Copy link
Copy Markdown
Author

The build failed under Ubuntu and Arch Linux.

Related to more strict warnings, likely fixed now.

Not yet...

I built locally with the same pedantic flags and pushed another try.

@Youw Youw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind the idea of having libudev loaded dynamically in runtime, but I can't agree that the current aproach is best for that. A few points I'd ask to change if I where to accept it this way:

  • licence shouldn't derive from libudev license - we don't copy-paste their code, and HIDAPI uses a bit different licencing sceme, and the new source that becomes a part of HIDAPI would potentially restrict its users;
  • including the .c file for this purpose looks a bit ugly, and the name libudev.c suggests that it actually is (i.e. implements) libudev, but in fact it is only a wrapper; what is best instead - have a hidapi_libudev_wrap.h, and all functions inside should be either static or inline;
  • the C() macro... I checked - it is a valid C, but the fact that I had to go and double-check suggests that it looks like something that might break; HIDAPI_UDEV_RESOLVE wouldn't raise any naming suspicious
  • RTLD_GLOBAL - that is a code smell to use it here, where passing the _lib (or rather udev_lib_handle to dlsym) explicitly is what I'd expect
  • no dlclose which is technically a resource leak if HIDAPI itself is ever to be dynamically loaded

At the end of the day - I'd be much happier to see a more common way of dynamically loading a library during the initialisation, saving and using function pointers explicitly and unloading a library during the hid_exit, e.g. like we did it for windows backend.

Yes that would cause a lot more changes in linux/hid.c - but that's absolutely fine.

Comment thread linux/CMakeLists.txt
@falkTX

falkTX commented Apr 24, 2026

Copy link
Copy Markdown
Author

That is all very fair, I mostly did this change as a way to get my cross-compilation builds working and decided to push it upstream because why not.

You have good points for something that would be integrated officially in hidapi, but sorry to say my needs are covered already as-is, the steps you mention make sense but sound like it would be quite a bit more work than I am willing to spend just for a small feature.

If you think the feature is worthwhile, take all the code here to adapt freely under any license, I give written consent.
This is as far as I go though, perhaps someone else can take over now.
Or otherwise feel free to close the PR too, I can understand that too.

@Youw Youw added build system/CI Anything related to building the project or running on CI Contributions Welcome Any external help is welcome don't_merge Don't merge this PR as is labels Apr 25, 2026
@Youw

Youw commented Apr 25, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution.

I'll leave it be for now, in case anyone wants to catch up.

Youw added 3 commits July 30, 2026 17:56
Load libudev.so.1 through a scoped runtime handle, resolve the required
entry points, and clean up partial and successful initialization state.
Remove the build-time libudev development dependency and cover reload,
failure recovery, and balanced unload behavior in Linux CI.

Assisted-by: codex:gpt-5.6-sol
Resolve the Linux loader and CI workflow conflicts while preserving the
upstream virtual-device tests and the PR's loader lifecycle coverage.

Assisted-by: codex:gpt-5.6-sol
Resolve workflow and pkg-config conflicts, preserve private libdl linkage,
and remove legacy author names from the new loader test files.

Assisted-by: codex:gpt-5.6-sol
@Youw Youw removed don't_merge Don't merge this PR as is Contributions Welcome Any external help is welcome labels Jul 30, 2026
Refresh copyright notices in the Linux loader sources changed by this PR.

Assisted-by: codex:gpt-5.6-sol
@Youw

Youw commented Jul 30, 2026

Copy link
Copy Markdown
Member

Anyone care to try this out?

@mcuee

mcuee commented Jul 30, 2026

Copy link
Copy Markdown
Member

Anyone care to try this out?

Just wondering how to properly test this PR. Thanks.

@Youw

Youw commented Jul 31, 2026

Copy link
Copy Markdown
Member
  • Ensure no libudev-dev package is installed (so libudev.h is not available)
  • Build locally from sources
  • Run and verify that enumeration/etc. works as usual

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build system/CI Anything related to building the project or running on CI hidraw Related to Linux/hidraw backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants