nut/m4/nut_check_libusb.m4

336 lines
12 KiB
Text
Raw Normal View History

2022-06-29 10:37:36 +00:00
dnl Check for LIBUSB 1.0 or 0.1 (and, if found, fill 'nut_usb_lib' with its
dnl approximate version) and its compiler flags. On success, set
dnl nut_have_libusb="yes" and set LIBUSB_CFLAGS and LIBUSB_LIBS. On failure, set
2010-03-25 23:20:59 +00:00
dnl nut_have_libusb="no". This macro can be run multiple times, but will
dnl do the checking only once.
2022-06-29 10:37:36 +00:00
dnl By default, if both libusb 1.0 and libusb 0.1 are available and appear to be
dnl usable, libusb 1.0 takes precedence.
dnl An optional argument with value 'libusb-1.0' or 'libusb-0.1' can be used to
dnl restrict checks to a specific version.
2010-03-25 23:20:59 +00:00
AC_DEFUN([NUT_CHECK_LIBUSB],
[
if test -z "${nut_have_libusb_seen}"; then
nut_have_libusb_seen=yes
2022-06-29 10:37:36 +00:00
NUT_CHECK_PKGCONFIG
2010-03-25 23:20:59 +00:00
2011-01-26 09:35:08 +00:00
dnl save CFLAGS and LIBS
2010-03-25 23:20:59 +00:00
CFLAGS_ORIG="${CFLAGS}"
2011-01-26 09:35:08 +00:00
LIBS_ORIG="${LIBS}"
2022-06-29 10:37:36 +00:00
CFLAGS=""
LIBS=""
2010-03-25 23:20:59 +00:00
2022-06-29 10:37:36 +00:00
dnl Magic-format string to hold chosen libusb version and its config-source
nut_usb_lib=""
dnl TOTHINK: What if there are more than 0.1 and 1.0 to juggle?
dnl TODO? Add libusb-compat (1.0 code with 0.1's API) to the mix?
AS_IF([test x"$have_PKG_CONFIG" = xyes],
[AC_MSG_CHECKING([for libusb-1.0 version via pkg-config])
LIBUSB_1_0_VERSION="`$PKG_CONFIG --silence-errors --modversion libusb-1.0 2>/dev/null`" \
&& test -n "${LIBUSB_1_0_VERSION}" \
|| LIBUSB_1_0_VERSION="none"
AC_MSG_RESULT([${LIBUSB_1_0_VERSION} found])
AC_MSG_CHECKING([for libusb(-0.1) version via pkg-config])
LIBUSB_0_1_VERSION="`$PKG_CONFIG --silence-errors --modversion libusb 2>/dev/null`" \
&& test -n "${LIBUSB_0_1_VERSION}" \
|| LIBUSB_0_1_VERSION="none"
AC_MSG_RESULT([${LIBUSB_0_1_VERSION} found])
],
[LIBUSB_0_1_VERSION="none"
LIBUSB_1_0_VERSION="none"
AC_MSG_NOTICE([can not check libusb settings via pkg-config])
]
)
dnl Note: it seems the script was only shipped for libusb-0.1
dnl So we don't separate into LIBUSB_0_1_CONFIG and LIBUSB_1_0_CONFIG
AC_PATH_PROGS([LIBUSB_CONFIG], [libusb-config], [none])
AC_ARG_WITH(libusb-config,
AS_HELP_STRING([@<:@--with-libusb-config=/path/to/libusb-config@:>@],
[path to program that reports LibUSB configuration]), dnl ...for LibUSB-0.1
[
AS_CASE(["${withval}"],
[""], [], dnl empty arg
[yes|no], [
dnl MAYBE bump preference of script over pkg-config?
AC_MSG_ERROR([invalid option --with(out)-libusb-config - see docs/configure.txt])
],
[dnl default
LIBUSB_CONFIG="${withval}"
]
)
]
)
AS_IF([test x"${LIBUSB_CONFIG}" != xnone],
[AC_MSG_CHECKING([via ${LIBUSB_CONFIG}])
LIBUSB_CONFIG_VERSION="`$LIBUSB_CONFIG --version 2>/dev/null`" \
&& test -n "${LIBUSB_CONFIG_VERSION}" \
|| LIBUSB_CONFIG_VERSION="none"
AC_MSG_RESULT([${LIBUSB_CONFIG_VERSION} found])
], [LIBUSB_CONFIG_VERSION="none"]
)
dnl By default, prefer newest available, and if anything is known
dnl to pkg-config, prefer that. Otherwise, fall back to script data:
AS_IF([test x"${LIBUSB_1_0_VERSION}" != xnone],
[LIBUSB_VERSION="${LIBUSB_1_0_VERSION}"
nut_usb_lib="(libusb-1.0)"
],
[AS_IF([test x"${LIBUSB_0_1_VERSION}" != xnone],
[LIBUSB_VERSION="${LIBUSB_0_1_VERSION}"
nut_usb_lib="(libusb-0.1)"
],
[LIBUSB_VERSION="${LIBUSB_CONFIG_VERSION}"
AS_IF([test x"${LIBUSB_CONFIG_VERSION}" != xnone],
[dnl TODO: This assumes 0.1; check for 1.0+ somehow?
nut_usb_lib="(libusb-0.1-config)"],
[nut_usb_lib=""]
)]
)]
)
dnl Pick up the default or caller-provided choice here from
dnl NUT_ARG_WITH(usb, ...) in the main configure.ac script
AC_MSG_CHECKING([for libusb preferred version])
AS_CASE(["${nut_with_usb}"],
[auto], [], dnl Use preference picked above
[yes], [], dnl Use preference from above, fail in the end if none found
[no], [], dnl Try to find, report in the end if that is discarded; TODO: not waste time?
[libusb-1.0|1.0], [
dnl NOTE: Assuming there is no libusb-config-1.0 or similar script, never saw one
AS_IF([test x"${LIBUSB_1_0_VERSION}" = xnone],
[AC_MSG_ERROR([option --with-usb=${withval} was required, but this library version was not detected])
])
LIBUSB_VERSION="${LIBUSB_1_0_VERSION}"
nut_usb_lib="(libusb-1.0)"
],
[libusb-0.1|0.1], [
AS_IF([test x"${LIBUSB_0_1_VERSION}" = xnone \
&& test x"${LIBUSB_CONFIG_VERSION}" = xnone],
[AC_MSG_ERROR([option --with-usb=${withval} was required, but this library version was not detected])
])
AS_IF([test x"${LIBUSB_0_1_VERSION}" != xnone],
[LIBUSB_VERSION="${LIBUSB_0_1_VERSION}"
nut_usb_lib="(libusb-0.1)"
],
[LIBUSB_VERSION="${LIBUSB_CONFIG_VERSION}"
nut_usb_lib="(libusb-0.1-config)"
])
],
[dnl default
AC_MSG_ERROR([invalid option value --with-usb=${withval} - see docs/configure.txt])
]
)
AC_MSG_RESULT([${LIBUSB_VERSION} ${nut_usb_lib}])
AS_IF([test x"${LIBUSB_1_0_VERSION}" != xnone && test x"${nut_usb_lib}" != x"(libusb-1.0)" ],
[AC_MSG_NOTICE([libusb-1.0 support was detected, but another was chosen ${nut_usb_lib}])]
)
dnl FIXME? Detect and report all CFLAGS/LIBS that we can,
dnl and *then* pick one set of values to use?
AS_CASE([${nut_usb_lib}],
["(libusb-1.0)"], [
CFLAGS="`$PKG_CONFIG --silence-errors --cflags libusb-1.0 2>/dev/null`"
LIBS="`$PKG_CONFIG --silence-errors --libs libusb-1.0 2>/dev/null`"
],
["(libusb-0.1)"], [
CFLAGS="`$PKG_CONFIG --silence-errors --cflags libusb 2>/dev/null`"
LIBS="`$PKG_CONFIG --silence-errors --libs libusb 2>/dev/null`"
],
["(libusb-0.1-config)"], [
CFLAGS="`$LIBUSB_CONFIG --cflags 2>/dev/null`"
LIBS="`$LIBUSB_CONFIG --libs 2>/dev/null`"
],
[dnl default, for other versions or "none"
AC_MSG_WARN([Defaulting libusb configuration])
2011-01-26 09:35:08 +00:00
LIBUSB_VERSION="none"
2010-03-25 23:20:59 +00:00
CFLAGS=""
2011-01-26 09:35:08 +00:00
LIBS="-lusb"
2022-06-29 10:37:36 +00:00
]
)
2010-03-25 23:20:59 +00:00
2022-06-29 10:37:36 +00:00
dnl check optional user-provided values for cflags/ldflags
dnl and publish what we end up using
2010-03-25 23:20:59 +00:00
AC_MSG_CHECKING(for libusb cflags)
2011-01-26 09:35:08 +00:00
AC_ARG_WITH(usb-includes,
AS_HELP_STRING([@<:@--with-usb-includes=CFLAGS@:>@], [include flags for the libusb library]),
[
2022-06-29 10:37:36 +00:00
AS_CASE(["${withval}"],
[yes|no], [
AC_MSG_ERROR(invalid option --with(out)-usb-includes - see docs/configure.txt)
],
[dnl default
CFLAGS="${withval}"
]
)
2011-01-26 09:35:08 +00:00
], [])
2010-03-25 23:20:59 +00:00
AC_MSG_RESULT([${CFLAGS}])
AC_MSG_CHECKING(for libusb ldflags)
2011-01-26 09:35:08 +00:00
AC_ARG_WITH(usb-libs,
AS_HELP_STRING([@<:@--with-usb-libs=LIBS@:>@], [linker flags for the libusb library]),
[
2022-06-29 10:37:36 +00:00
AS_CASE(["${withval}"],
[yes|no], [
AC_MSG_ERROR(invalid option --with(out)-usb-libs - see docs/configure.txt)
],
[dnl default
LIBS="${withval}"
]
)
2011-01-26 09:35:08 +00:00
], [])
AC_MSG_RESULT([${LIBS}])
2010-03-25 23:20:59 +00:00
2022-06-29 10:37:36 +00:00
dnl TODO: Consult chosen nut_usb_lib value and/or nut_with_usb argument
dnl (with "auto" we may use a 0.1 if present and working while a 1.0 is
dnl present but useless)
dnl Check if libusb is usable
AC_LANG_PUSH([C])
if test -n "${LIBUSB_VERSION}"; then
dnl Test specifically for libusb-1.0 via pkg-config, else fall back below
test -n "$PKG_CONFIG" \
&& test x"${nut_usb_lib}" = x"(libusb-1.0)" \
&& $PKG_CONFIG --silence-errors --atleast-version=1.0 libusb-1.0 2>/dev/null
if test "$?" = "0"; then
dnl libusb 1.0: libusb_set_auto_detach_kernel_driver
AC_CHECK_HEADERS(libusb.h, [nut_have_libusb=yes], [nut_have_libusb=no], [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS(libusb_init, [], [nut_have_libusb=no])
AC_CHECK_FUNCS(libusb_strerror, [], [nut_have_libusb=no; nut_have_libusb_strerror=no])
if test "${nut_have_libusb_strerror}" = "no"; then
AC_MSG_WARN([libusb_strerror() not found; install libusbx to use libusb 1.0 API. See https://github.com/networkupstools/nut/issues/509])
fi
if test "${nut_have_libusb}" = "yes"; then
dnl This function is fairly old, but check for it anyway:
AC_CHECK_FUNCS(libusb_kernel_driver_active)
dnl Check for libusb "force driver unbind" availability
AC_CHECK_FUNCS(libusb_set_auto_detach_kernel_driver)
dnl libusb 1.0: libusb_detach_kernel_driver
dnl FreeBSD 10.1-10.3 have this, but not libusb_set_auto_detach_kernel_driver
AC_CHECK_FUNCS(libusb_detach_kernel_driver)
AC_CHECK_FUNCS(libusb_detach_kernel_driver_np)
2010-03-25 23:20:59 +00:00
2022-06-29 10:37:36 +00:00
dnl From libusb-0.1 - check these to have valid config.h definitions
dnl Note: confusingly, FreeBSD does find both as defined
dnl (despite being spread across usb.h and libusb.h),
dnl so our source code has to care :\
AC_CHECK_FUNCS(usb_detach_kernel_driver_np)
fi
else
dnl libusb 0.1, or missing pkg-config :
AC_CHECK_HEADERS(usb.h, [nut_have_libusb=yes], [nut_have_libusb=no], [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS(usb_init, [], [
dnl Some systems may just have libusb in their standard
dnl paths, but not the pkg-config or libusb-config data
AS_IF([test "${nut_have_libusb}" = "yes" && test "$LIBUSB_VERSION" = "none" && test -z "$LIBS"],
[AC_MSG_CHECKING([if libusb is just present in path])
LIBS="-L/usr/lib -L/usr/local/lib -lusb"
unset ac_cv_func_usb_init || true
AC_CHECK_FUNCS(usb_init, [], [nut_have_libusb=no])
AC_MSG_RESULT([${nut_have_libusb}])
], [nut_have_libusb=no]
)]
)
dnl Check for libusb "force driver unbind" availability
if test "${nut_have_libusb}" = "yes"; then
AC_CHECK_FUNCS(usb_detach_kernel_driver_np)
dnl From libusb-1.0 - check these to have valid config.h definitions
AC_CHECK_FUNCS(libusb_kernel_driver_active)
AC_CHECK_FUNCS(libusb_set_auto_detach_kernel_driver)
AC_CHECK_FUNCS(libusb_detach_kernel_driver)
AC_CHECK_FUNCS(libusb_detach_kernel_driver_np)
fi
fi
else
nut_have_libusb=no
fi
AS_IF([test "${nut_have_libusb}" = "yes"], [
dnl ----------------------------------------------------------------------
dnl additional USB-related checks
dnl Solaris 10/11 USB handling (need librt and libusb runtime path)
dnl Should we check for `uname -o == illumos` to avoid legacy here?
dnl Or better yet, perform some active capability tests for need of
dnl workarounds or not? e.g. OpenIndiana should include a capable
dnl version of libusb-1.0.23+ tailored with NUT tests in mind...
dnl HPUX, since v11, needs an explicit activation of pthreads
dnl TODO: There are reports about FreeBSD error-code
dnl handling in libusb-0.1 port returning "-1" always,
dnl instead of differing codes like on other systems.
dnl Should we check for that below?..
dnl https://github.com/networkupstools/nut/issues/490
AS_CASE(["${target_os}"],
[solaris2.1*], [
AC_MSG_CHECKING([for Solaris 10 / 11 specific configuration for usb drivers])
AC_SEARCH_LIBS(nanosleep, rt)
LIBS="-R/usr/sfw/lib ${LIBS}"
dnl FIXME: Sun's libusb doesn't support timeout (so blocks notification)
dnl and need to call libusb close upon reconnection
dnl TODO: Somehow test for susceptible versions?
AC_DEFINE(SUN_LIBUSB, 1, [Define to 1 for Sun version of the libusb.])
SUN_LIBUSB=1
AC_MSG_RESULT([${LIBS}])
],
[hpux11*], [
CFLAGS="${CFLAGS} -lpthread"
]
)
])
AC_LANG_POP([C])
AS_IF([test "${nut_have_libusb}" = "yes"], [
2010-03-25 23:20:59 +00:00
LIBUSB_CFLAGS="${CFLAGS}"
2011-01-26 09:35:08 +00:00
LIBUSB_LIBS="${LIBS}"
2022-06-29 10:37:36 +00:00
], [
AS_CASE(["${nut_with_usb}"],
[no|auto], [],
[yes|1.0|0.1|libusb-1.0|libusb-0.1],
[dnl Explicitly choosing a library implies 'yes' (i.e. fail if not found), not 'auto'.
AC_MSG_ERROR([USB drivers requested, but libusb not found.])
]
)
])
if test "${nut_with_usb}" = "no"; then
if test -n "${nut_usb_lib}" && test "${nut_usb_lib}" != none ; then
AC_MSG_NOTICE([libusb was detected ${nut_usb_lib}, but a build without USB drivers was requested])
fi
nut_usb_lib=""
else
nut_with_usb="${nut_have_libusb}"
2010-03-25 23:20:59 +00:00
fi
2022-06-29 10:37:36 +00:00
dnl AC_MSG_NOTICE([DEBUG: nut_have_libusb='${nut_have_libusb}'])
dnl AC_MSG_NOTICE([DEBUG: nut_with_usb='${nut_with_usb}'])
dnl AC_MSG_NOTICE([DEBUG: nut_usb_lib='${nut_usb_lib}'])
dnl Note: AC_DEFINE specifies a verbatim "value" so we pre-calculate it!
dnl Source code should be careful to use "#if" and not "#ifdef" when
dnl checking these values during the build. And both must be defined
dnl with some value.
AS_IF([test "${nut_with_usb}" = "yes" && test "${nut_usb_lib}" = "(libusb-1.0)"],
[AC_DEFINE([WITH_LIBUSB_1_0], [1],
[Define to 1 for version 1.0 of the libusb (via pkg-config).])],
[AC_DEFINE([WITH_LIBUSB_1_0], [0],
[Define to 1 for version 1.0 of the libusb (via pkg-config).])]
)
AS_IF([test "${nut_with_usb}" = "yes" && test "${nut_usb_lib}" = "(libusb-0.1)" -o "${nut_usb_lib}" = "(libusb-0.1-config)"],
[AC_DEFINE([WITH_LIBUSB_0_1], [1],
[Define to 1 for version 0.1 of the libusb (via pkg-config or libusb-config).])],
[AC_DEFINE([WITH_LIBUSB_0_1], [0],
[Define to 1 for version 0.1 of the libusb (via pkg-config or libusb-config).])]
)
2011-01-26 09:35:08 +00:00
dnl restore original CFLAGS and LIBS
2010-03-25 23:20:59 +00:00
CFLAGS="${CFLAGS_ORIG}"
2011-01-26 09:35:08 +00:00
LIBS="${LIBS_ORIG}"
2010-03-25 23:20:59 +00:00
fi
])