Skip to content

Commit cd95af8

Browse files
authored
libusb: cmake: Proper dependency on Iconv (#405)
- explicitly add Iconv as a dependent library; - check if iconv requires pointer-to-const as input (introduce ICONV_CONST check); - NetBSD CI (has external Iconv library implementation that uses all of the above);
1 parent 874b29c commit cd95af8

File tree

5 files changed

+62
-2
lines changed

5 files changed

+62
-2
lines changed

.builds/netbsd.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
image: netbsd/latest
2+
packages:
3+
- cmake
4+
- pkgconf
5+
- libusb1
6+
- libiconv
7+
sources:
8+
- https://github.com/libusb/hidapi
9+
tasks:
10+
- setup: |
11+
cd hidapi
12+
mkdir -p build install
13+
cmake -B build -S . -DCMAKE_INSTALL_PREFIX=install
14+
- build: |
15+
cd hidapi/build
16+
make
17+
make install
18+
make clean

libusb/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,29 @@ endif()
1919
find_package(Threads REQUIRED)
2020
target_link_libraries(hidapi_libusb PRIVATE Threads::Threads)
2121

22+
if(HIDAPI_NO_ICONV)
23+
target_compile_definitions(hidapi_libusb PRIVATE NO_ICONV)
24+
else()
25+
if(NOT ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.11)
26+
find_package(Iconv REQUIRED)
27+
include(CheckCSourceCompiles)
28+
target_link_libraries(hidapi_libusb PRIVATE Iconv::Iconv)
29+
set(CMAKE_REQUIRED_LIBRARIES "Iconv::Iconv")
30+
# check for error: "conflicting types for 'iconv'"
31+
check_c_source_compiles("#include<iconv.h>
32+
extern size_t iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
33+
int main() {}"
34+
HIDAPI_ICONV_CONST)
35+
if(HIDAPI_ICONV_CONST)
36+
target_compile_definitions(hidapi_libusb PRIVATE "ICONV_CONST=const")
37+
endif()
38+
endif()
39+
# otherwise there is 3 options:
40+
# 1) On Android Iconv is disabled on the code level anyway, so no issue;
41+
# 2) iconv is provided by Standard C library and the build will be just fine;
42+
# 4) The _user_ has to provide additiona compilation options for this project/target.
43+
endif()
44+
2245
set_target_properties(hidapi_libusb
2346
PROPERTIES
2447
EXPORT_NAME "libusb"

libusb/hid.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
#include <libusb.h>
4545
#if !defined(__ANDROID__) && !defined(NO_ICONV)
4646
#include <iconv.h>
47+
#ifndef ICONV_CONST
48+
#define ICONV_CONST
49+
#endif
4750
#endif
4851

4952
#include "hidapi_libusb.h"
@@ -405,7 +408,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
405408
size_t inbytes;
406409
size_t outbytes;
407410
size_t res;
408-
char *inptr;
411+
ICONV_CONST char *inptr;
409412
char *outptr;
410413
#endif
411414

@@ -421,7 +424,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
421424
lang,
422425
(unsigned char*)buf,
423426
sizeof(buf));
424-
if (len < 0)
427+
if (len < 2) /* we always skip first 2 bytes */
425428
return NULL;
426429

427430
#if defined(__ANDROID__) || defined(NO_ICONV)

src/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ set(EXPORT_COMPONENTS)
9292
set(HIDAPI_NEED_EXPORT_THREADS FALSE)
9393
set(HIDAPI_NEED_EXPORT_LIBUSB FALSE)
9494
set(HIDAPI_NEED_EXPORT_LIBUDEV FALSE)
95+
set(HIDAPI_NEED_EXPORT_ICONV FALSE)
9596

9697
if(WIN32)
9798
add_subdirectory("${PROJECT_ROOT}/windows" windows)
@@ -128,6 +129,9 @@ else()
128129
target_include_directories(hidapi_include INTERFACE
129130
"$<BUILD_INTERFACE:${PROJECT_ROOT}/libusb>"
130131
)
132+
if(NOT DEFINED HIDAPI_NO_ICONV)
133+
set(HIDAPI_NO_ICONV OFF)
134+
endif()
131135
add_subdirectory("${PROJECT_ROOT}/libusb" libusb)
132136
list(APPEND EXPORT_COMPONENTS libusb)
133137
if(NOT EXPORT_ALIAS)
@@ -138,6 +142,9 @@ else()
138142
if(NOT TARGET usb-1.0)
139143
set(HIDAPI_NEED_EXPORT_LIBUSB TRUE)
140144
endif()
145+
if(NOT HIDAPI_NO_ICONV AND NOT ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.11)
146+
set(HIDAPI_NEED_EXPORT_ICONV TRUE)
147+
endif()
141148
endif()
142149
elseif(NOT TARGET hidapi_hidraw)
143150
message(FATAL_ERROR "Select at least one option to build: HIDAPI_WITH_LIBUSB or HIDAPI_WITH_HIDRAW")

src/cmake/hidapi-config.cmake.in

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ set(hidapi_FOUND FALSE)
1111
set(HIDAPI_NEED_EXPORT_THREADS @HIDAPI_NEED_EXPORT_THREADS@)
1212
set(HIDAPI_NEED_EXPORT_LIBUSB @HIDAPI_NEED_EXPORT_LIBUSB@)
1313
set(HIDAPI_NEED_EXPORT_LIBUDEV @HIDAPI_NEED_EXPORT_LIBUDEV@)
14+
set(HIDAPI_NEED_EXPORT_ICONV @HIDAPI_NEED_EXPORT_ICONV@)
1415

1516
if(HIDAPI_NEED_EXPORT_THREADS)
1617
if(CMAKE_VERSION VERSION_LESS 3.4.3)
@@ -32,6 +33,14 @@ if(HIDAPI_NEED_EXPORT_LIBUSB OR HIDAPI_NEED_EXPORT_LIBUDEV)
3233
endif()
3334
endif()
3435

36+
if(HIDAPI_NEED_EXPORT_ICONV)
37+
if(CMAKE_VERSION VERSION_LESS 3.11)
38+
message(WARNING "HIDAPI requires CMake target Iconv::Iconv, make sure to provide it")
39+
else()
40+
find_package(Iconv REQUIRED)
41+
endif()
42+
endif()
43+
3544
include("${CMAKE_CURRENT_LIST_DIR}/libhidapi.cmake")
3645

3746
set(hidapi_FOUND TRUE)

0 commit comments

Comments
 (0)