Skip to content

Fix HID-enabled build automoc registration#2577

Merged
ten9876 merged 1 commit into
aethersdr:mainfrom
rfoust:codex/fix-hid-automoc
May 12, 2026
Merged

Fix HID-enabled build automoc registration#2577
ten9876 merged 1 commit into
aethersdr:mainfrom
rfoust:codex/fix-hid-automoc

Conversation

@rfoust

@rfoust rfoust commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • include the HID headers in the conditional hidapi target source list
  • ensure Qt AUTOMOC sees HidEncoderManager.h when HAVE_HIDAPI is enabled
  • fixes HID-enabled builds that currently fail at link time with missing HidEncoderManager Qt meta-object/signal symbols

Bug

AetherSDR builds normally when hidapi is not installed because the HID encoder code is skipped. After installing the optional hidapi dependency, CMake enables HAVE_HIDAPI and compiles HidEncoderManager.cpp.

HidEncoderManager inherits QObject and uses Q_OBJECT/signals in HidEncoderManager.h. Qt must run MOC on that header to generate the class meta-object, signal methods, and vtable-related code. The current hidapi-enabled target_sources() block only lists the .cpp files, so AUTOMOC does not reliably scan HidEncoderManager.h.

That causes the HID-enabled build to compile but fail during the final app link with missing symbols such as:

  • AetherSDR::HidEncoderManager::staticMetaObject
  • AetherSDR::HidEncoderManager::buttonPressed(...)
  • AetherSDR::HidEncoderManager::connectionChanged(...)
  • vtable for AetherSDR::HidEncoderManager

Fix

Add the HID headers to the same conditional target_sources() block used when HIDAPI_FOUND is true:

  • src/core/HidEncoderManager.h
  • src/core/HidDeviceParser.h

The key file is HidEncoderManager.h because it contains Q_OBJECT. Listing it as a target source lets Qt AUTOMOC generate the missing meta-object/signal code. HidDeviceParser.h is included alongside its matching .cpp for consistency.

Testing

Configured and built on macOS with optional hidapi installed:

  • cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo
  • cmake --build build

CMake reported:

  • hidapi found — USB HID encoder support enabled

The app linked successfully after this change.

Copilot AI review requested due to automatic review settings May 11, 2026 08:37
@rfoust rfoust requested a review from ten9876 as a code owner May 11, 2026 08:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Fixes HID-enabled builds by ensuring Qt’s AUTOMOC processes the HID QObject header when hidapi support is enabled, preventing missing meta-object/signal symbol link errors.

Changes:

  • Add src/core/HidEncoderManager.h to the HIDAPI conditional target_sources() list so MOC is generated for the Q_OBJECT class.
  • Add src/core/HidDeviceParser.h alongside its .cpp for consistent source registration under HIDAPI_FOUND.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ten9876 ten9876 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Claude here, reviewing on Jeremy's behalf.

Verdict

Clean, trivial-but-important fix. Merge.

Verified

  • Q_OBJECT is present in HidEncoderManager.h — confirmed by direct grep. HidDeviceParser.h does not contain Q_OBJECT (listed only for consistency with its .cpp pairing).
  • Current CMakeLists.txt HIDAPI block only lists .cpp files — confirmed at the block starting around the HIDAPI_FOUND conditional. The PR adds the two .h files to the same target_sources() call.
  • CI all greenbuild, analyze (cpp), check-paths, check-windows, CodeQL. check-windows ran (not skipped) because CMakeLists.txt changed.
  • Built locally with hidapi installed — Linux clean build, MOC produced build/AetherSDR_autogen/PRMOGMWJPH/moc_HidEncoderManager.cpp correctly, link succeeded.

Why this fix is the right one

Qt's AUTOMOC has two ways to find Q_OBJECT in a header:

  1. Explicit: the header is listed in target_sources() — guaranteed scan
  2. Implicit: a listed .cpp #includes the header — AUTOMOC follows the include and scans

The implicit path is fragile in practice. It can break with:

  • Generator differences (Ninja vs. Xcode vs. VS — the failure Pat hit on macOS, where the generator may be Xcode-style)
  • AUTOMOC_DEPEND_FILTERS edge cases
  • Header that's forward-declared in the .cpp instead of #included directly
  • Cross-build / install-tree relocation

The explicit path (this PR) is the canonical Qt + CMake idiom and works identically across every generator. This is the right level to fix it at.

My Linux box happens to build successfully without the fix because AUTOMOC's implicit detection works in this configuration — the fact that Pat's macOS build fails is the standard "works on my machine" trap that the explicit fix eliminates. No need to characterize why the implicit path failed on Pat's setup; the explicit fix removes the dependency on that fragile heuristic entirely.

Recommendation

Merge. Trivial, correctly diagnosed, makes builds reproducible across generators and platforms.

Thanks @rfoust — these CMake-script papercuts are the kind that silently bite contributors trying to enable optional features. Documenting the AUTOMOC mechanism in the PR description is a nice touch that future archaeologists will appreciate.

73, Jeremy KK7GWY & Claude (AI dev partner)

@ten9876 ten9876 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved — correct AUTOMOC fix, built clean locally.

@ten9876 ten9876 merged commit a4a2a8b into aethersdr:main May 12, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants