Skip to content

cmake: add HIDAPI_BUILD_AS_CXX to compile sources as C++ - #814

Merged
Youw merged 1 commit into
masterfrom
cmake-build-as-cxx
May 21, 2026
Merged

cmake: add HIDAPI_BUILD_AS_CXX to compile sources as C++#814
Youw merged 1 commit into
masterfrom
cmake-build-as-cxx

Conversation

@Youw

@Youw Youw commented May 21, 2026

Copy link
Copy Markdown
Member

What

Add an opt-in CMake variable HIDAPI_BUILD_AS_CXX that wires set_source_files_properties(... LANGUAGE CXX) on every backend's C source file, so the file is compiled with the project's C++ compiler instead of the C compiler. Useful as a portability check — to confirm hidapi sources remain compatible with consumers that embed them into a C++ translation unit.

The variable is declared as a plain if(NOT DEFINED ...) default rather than via option(), so it doesn't appear in cmake-gui or cmake -L output. It is documented under "Testing-only variables" in BUILD.cmake.md.

# Enable from the command line:
cmake -B build -S . -DHIDAPI_BUILD_AS_CXX=ON \
    "-DCMAKE_CXX_FLAGS=-Wall -Wextra -Werror"
cmake --build build

Wired through every backend: linux, libusb, mac, netbsd, and windows (both hid.c and hidapi_descriptor_reconstruct.c).

Source touches

Three small adjustments to mac/hid.c so Apple Clang accepts the source as C++:

  • cast CFTypeRef to CFNumberRef at the CFNumberGetValue() call (C allows implicit void*-to-pointer conversion; C++ does not);
  • mark BUF_LEN const so the surrounding stack buffer is a non-VLA array (C99 VLAs are a Clang extension under C++);
  • cast calloc()'s return value when assigning to cur_dev->path, matching the cast pattern already used elsewhere in mac/hid.c.

Linux, libusb (post-#811) and the Windows backend already compile cleanly as C++; no source changes were needed there.

CI

To guard the option against regressions, three CI jobs in builds.yml get a new step that runs a full CMake build with HIDAPI_BUILD_AS_CXX=ON:

  • ubuntu-cmake — exercises hidapi_hidraw + hidapi_libusb under g++.
  • macos-cmake — exercises hidapi_darwin under Apple Clang.
  • windows-cmake — exercises hidapi_winapi under MSVC; also sets -DCMAKE_CXX_STANDARD=20 so the designated initialisers in windows/hid.c / windows/hidapi_descriptor_reconstruct.c parse as ISO C++ (under g++ / Clang's default mode they're a GNU extension; ISO C++ accepted them only since C++20).

-pedantic is intentionally omitted from the C++ check: libusb.h declares zero-size arrays, which g++ rejects under strict ISO C++ regardless of how hidapi itself is written. The existing C-build CI steps continue to test with -pedantic.

Local verification

Tested in WSL Ubuntu (gcc/g++ 11.4) — both Linux-side backends compile cleanly:

[ 25%] Building CXX object src/linux/CMakeFiles/hidapi_hidraw.dir/hid.c.o
[ 50%] Building CXX object src/libusb/CMakeFiles/hidapi_libusb.dir/hid.c.o
[ 75%] Linking CXX shared library libhidapi-hidraw.so
[100%] Linking CXX shared library libhidapi-libusb.so
build exit=0

CMake reports Building CXX object for the .c sources (because of the LANGUAGE CXX source property), and the produced shared libraries still export the API with C linkage — hidapi.h's existing extern "C" wrapper handles that — so the option doesn't break consumers if it's accidentally turned on. The mac and Windows-MSVC paths are covered by CI.

Drafted with Claude Code.

Add an opt-in CMake variable HIDAPI_BUILD_AS_CXX that, when set to
TRUE, attaches LANGUAGE CXX to each backend's C source file so it is
compiled with the C++ compiler instead of the C compiler. Useful as a
portability check, to confirm hidapi sources remain compatible with
consumers that embed them into a C++ translation unit.

The variable is intentionally not declared as a CMake option(), so it
is not surfaced in cmake-gui or `cmake -L` output. It is documented
under "Testing-only variables" in BUILD.cmake.md.

Wire it through every backend (linux, libusb, mac, netbsd, windows).
For the windows backend, both hid.c and hidapi_descriptor_reconstruct.c
are re-tagged.

Three small mac/hid.c adjustments are required for Apple Clang to
accept the source as C++:
  - cast CFTypeRef to CFNumberRef at CFNumberGetValue() (C allows
    implicit void*-to-pointer conversion; C++ does not);
  - mark BUF_LEN const so the stack buffer is a non-VLA array;
  - cast calloc()'s return value when assigning to cur_dev->path.

CI: enable HIDAPI_BUILD_AS_CXX=ON on the ubuntu-cmake, macos-cmake
and windows-cmake jobs to guard against regressions. The MSVC variant
also sets CMAKE_CXX_STANDARD=20 so the designated initialisers in the
Windows backend compile as ISO C++ (g++ and Clang accept them as a
GNU extension in their default mode).

Assisted-by: Claude:claude-opus-4.7
@Youw
Youw force-pushed the cmake-build-as-cxx branch from 168bc0c to 5c5c840 Compare May 21, 2026 07:54
@Youw
Youw merged commit c3509c1 into master May 21, 2026
23 checks passed
@Youw
Youw deleted the cmake-build-as-cxx branch May 21, 2026 08:12
@mcuee mcuee added build system/CI Anything related to building the project or running on CI CMake Related to CMake build system labels May 21, 2026
Youw added a commit that referenced this pull request Jul 13, 2026
The HIDAPI_BUILD_AS_CXX check (from #814, merged from master) rejected
the hotplug code: out-of-order/partial designated initializers on the
static hotplug contexts, int-to-enum conversions on the callback events
bitmask, and an uncast calloc. Replace the static initializers with
zero-initialized storage plus lazy next_handle setup, make the internal
events field a plain int bitmask, and cast the remaining sites.

Assisted-by: claude-code:claude-fable-5
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 CMake Related to CMake build system

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants