Skip to content

build: libusb-1.0 from 1.0.9 on, fall back to libusb-0.1 if too old - #3782

Open
nmbro wants to merge 5 commits into
networkupstools:masterfrom
nmbro:configure-libusb-auto-fallback
Open

nmbro wants to merge 5 commits into
networkupstools:masterfrom
nmbro:configure-libusb-auto-fallback

Conversation

@nmbro

@nmbro nmbro commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #3781, found while researching which platforms still need libusb-0.1 for #1507.

Problem

  • configure required libusb_strerror() (libusb 1.0.16+, Add autoconf check for libusb_strerror() #509) to use the libusb-1.0 API, so e.g. the libusb1 1.0.9 package of CentOS 6.3-6.10 was rejected.
  • With --with-usb=auto (or yes), a rejected libusb-1.0 also disabled USB drivers entirely, without trying an available libusb-0.1: the 0.1 checks only ran when pkg-config did not know libusb-1.0 at all.

Building current master against libusb 1.0.9 with that check bypassed showed only two methods missing: libusb_strerror() and libusb_get_version().

Changes

  1. build: accept libusb-1.0 from 1.0.9 on
    • configure: accept libusb_error_name() (1.0.9+) when libusb_strerror() is missing; check for libusb_get_version(). Both the detection and the cached pass.
    • usb-common.h: without libusb_strerror(), map it to libusb_error_name(). Log messages then show the code name (e.g. LIBUSB_ERROR_TIMEOUT) instead of a description.
    • libusb1.c: without libusb_get_version(), driver.version.usb reports libusb-1.0 (version unknown, 1.0.9 or older).
    • nut-scanner: if the libusb loaded at run time lacks libusb_strerror(), use libusb_error_name(); a missing libusb_get_version() is treated as an unknown (old) version instead of failing to load the library. struct libusb_version is mirrored (stable ABI) for builds against headers that lack it, so a newer run-time libusb can still be asked.
  2. build: fall back to libusb-0.1 if libusb-1.0 is too old
    • When the libusb-1.0 picked by preference does not link with libusb_init() and libusb_error_name(), and a libusb-0.1 was also detected, switch to libusb-0.1 before computing flags, with a notice. Explicit --with-usb=libusb-1.0 or custom --with-usb-includes/--with-usb-libs still fail as before. Replaces an existing TODO comment about this case.

Testing

Built against headers and libraries extracted from the CentOS 6.0/6.10 RPMs (PKG_CONFIG_LIBDIR/PKG_CONFIG_SYSROOT_DIR, host GCC; the centos:6 container itself does not run on a current kernel without vsyscall=emulate):

libusb installed --with-usb= Result
1.0.9 auto libusb-1.0; all USB drivers and nut-scanner build, no new warnings
1.0.9 + 0.1.12 auto keeps libusb-1.0
1.0.3 + 0.1.12 auto falls back to libusb-0.1; all USB drivers build
1.0.3 libusb-1.0 fails: neither libusb_strerror() nor libusb_error_name()
host 1.0.27 auto, --enable-Werror unchanged; drivers and nut-scanner build clean
host 1.0.27 + EL6 0.1.12 auto probe passes, keeps 1.0.27

Also: cached configure -C re-run of the fallback case; the first commit alone against 1.0.9; nut-scanner built against 1.0.27 run with the 1.0.9 library (both fallbacks taken, library loads, scan runs) and vice versa; make distcheck-light; make spellcheck. Not tested with USB devices on libusb 1.0.9.

libusb 1.0.3 (CentOS 6.0-6.2 only; a yum update brings 1.0.9) would additionally need a fallback for libusb_error_name(), libusb_handle_events_timeout() for the _completed variant (used by apcmicrolink), and an empty LIBUSB_CALL; I left that out.

Checklist

  • Described the changes in the PR submission
  • Multiple commits, each with a functional change
  • Use of coding helper tools and AI disclosed: Claude Code was used for development assistance
  • Revised for NUT code style and ASCII-only text; configure probes are guarded, no new pragmas
  • make distcheck-light passes
  • Added bullet points into NEWS.adoc
  • Passed make spellcheck

🤖 Generated with Claude Code

nmbro and others added 2 commits October 19, 2026 02:31
configure required libusb_strerror() (libusb 1.0.16+, see networkupstools#509) to use
the libusb-1.0 API, so e.g. the libusb1 1.0.9 package of CentOS 6 was
rejected. Building against it showed only one other method missing:
libusb_get_version().

* configure: accept libusb_error_name() (1.0.9+) when libusb_strerror()
  is missing, and check for libusb_get_version().
* usb-common.h: map libusb_strerror() to libusb_error_name() when the
  former is missing; messages then show the error code name.
* libusb1.c: without libusb_get_version(), report the libusb version
  in driver.version.usb as unknown.
* nut-scanner: when the libusb loaded at run time lacks
  libusb_strerror(), use libusb_error_name(); treat a missing
  libusb_get_version() as an unknown (old) version instead of failing
  to load the library. Mirror struct libusb_version for builds against
  headers that lack it.

Tested by building against the headers and libraries from the CentOS
6.10 RPMs (host GCC), and by running nut-scanner built against libusb
1.0.27 with the 1.0.9 library and vice versa. Not tested with devices.

Refs: networkupstools#3781

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: nmbro <nmbro@users.noreply.github.com>
With --with-usb=auto (or yes), configure picks libusb-1.0 whenever
pkg-config knows it. If that libusb-1.0 then failed the usability
checks, the libusb-0.1 checks were never tried and configure silently
built no USB drivers, even with a usable libusb-0.1 installed.

When the libusb-1.0 picked by preference does not link with
libusb_init() and libusb_error_name() (libusb 1.0.9+), and a libusb-0.1
was also detected, switch to libusb-0.1 before computing the flags and
say so in a notice. An explicit --with-usb=libusb-1.0, or custom
--with-usb-includes/--with-usb-libs, still fails as before.

Tested with the CentOS 6.0 libusb1 1.0.3 + libusb 0.1.12 RPM contents
(falls back, builds all drivers), 1.0.9 + 0.1.12 (keeps 1.0.9), and the
host libusb 1.0.27 (unchanged), including a cached configure re-run.

Closes: networkupstools#3781

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: nmbro <nmbro@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

A ZIP file with standard source tarball and another tarball with pre-built docs for commit 8ca85cf is temporarily available: NUT-tarballs-PR-3782.zip.

@jimklimov jimklimov 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.

Looks superb, thanks!

@jimklimov jimklimov added USB CI Entries related to continuous integration infrastructure (here CI = tools + scripts + recipes) portability We want NUT to build and run everywhere possible AI For good or bad, machine tools are upon us. Humans are still the responsible ones. labels Oct 19, 2026
@jimklimov jimklimov added this to the 2.8.6 milestone Oct 19, 2026
Resolve the NEWS.adoc conflict with master (both sides added entries
at the same place; keep both), and add the PR number to this branch's
NEWS references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: nmbro <nmbro@users.noreply.github.com>
nmbro added a commit to nmbro/nut that referenced this pull request Oct 21, 2026
The libusb-1.0.9 and libusb-0.1 fallback entries come from the commits of PR networkupstools#3782, which this branch builds on; use the same references there and here, so either PR merges cleanly after the other.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: nmbro <nmbro@users.noreply.github.com>
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 21, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 23, 2026
With autoconf 2.69, a line break between the last line of an AS_IF
condition and its closing bracket makes the generated configure read
"if <condition>" followed by a line starting with "; then :", which is
a shell syntax error. autogen.sh rejects such a configure in its
"$CONFIG_SHELL -n configure" check, which failed every Jenkins stage
that runs autogen.sh on CentOS 7, Debian 11, Ubuntu trusty/impish,
Slackware 15 and OpenBSD 6.5 for this PR. autoconf 2.70 and newer
emit "then :" without the semicolon, so newer systems were not hit.

Reproduced with autoconf 2.69 (dash -n and bash -n on the generated
configure); with this change both pass, as does configure from
autoconf 2.73.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: nmbro <nmbro@users.noreply.github.com>
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 27, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 27, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 27, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 27, 2026
@AppVeyorBot

Copy link
Copy Markdown

✅ Build nut 2.8.5.5921-master completed (commit 14a50ef4fb by @nmbro)

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

Labels

AI For good or bad, machine tools are upon us. Humans are still the responsible ones. CI Entries related to continuous integration infrastructure (here CI = tools + scripts + recipes) portability We want NUT to build and run everywhere possible USB

Projects

None yet

Development

Successfully merging this pull request may close these issues.

configure: --with-usb=auto does not fall back to libusb-0.1 when libusb-1.0 is too old

3 participants