feat: add pure C shim layer for cross-compiler ABI safety#1
Merged
Conversation
Introduce a shim layer between the Node.js addon (MSVC) and Hamlib
(MinGW), eliminating the MSVC/MinGW struct layout incompatibility
that caused immediate crashes on Windows when importing the module.
Architecture:
Node.js → hamlib.node (C++ NAPI, MSVC) → hamlib_shim (pure C) → libhamlib
Key changes:
- New src/shim/hamlib_shim.{h,c}: ~95 pure C wrapper functions with
opaque handle pattern, replacing all direct Hamlib struct accesses
- Rewrite src/hamlib.cpp to use shim_rig_* functions exclusively
(no conditional compilation, all platforms use same code path)
- New scripts/build-shim.js: cross-platform shim build script
(static .a on Linux/macOS, DLL on Windows via MinGW)
- Simplified binding.gyp: removed complex Hamlib path search logic,
pthread dependency, and MinGW conditional compilation for Windows
- Updated CI: added MSYS2/MinGW setup for Windows shim DLL build
- Removed obsolete hamlib_compat.h and 7 temporary debug scripts
Verified on Windows: module loads and all 84 API methods work correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Unix, build-all.js handles hamlib setup + shim build + addon build in sequence. On Windows, shim DLL is built separately via MSYS2 before the MSVC addon build. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The MSYS2 shell doesn't have Node.js in PATH. Use pwsh shell instead and set MINGW_CC to point to the MSYS2 MinGW gcc. Also add fail-fast: false to allow all platform builds to complete independently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
prebuildify internally runs node-gyp rebuild which cleans the build/ directory, deleting the previously built shim .a/.lib files. Moving shim output to a separate shim-build/ directory prevents this. Also adds pip install setuptools to CI for Python 3.12 compatibility with node-gyp 9.4.1 (distutils was removed in Python 3.12). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dynamic linker needs the soname-versioned file (e.g., libhamlib.so.5) but the bundler was only copying a single file. Now copies all libhamlib.so* files from the lib directory, resolving symlinks. Also improved findHamlibSo() to search for any version (so.4, so.5, etc.) instead of hardcoding so.4. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds test_ci_functional.js that validates the compiled binary actually works by exercising core API operations against the Hamlib Dummy device (Model 1). Tests VFO, frequency, PTT, serial config, power control, and instance lifecycle - no rigctld or hardware needed. CI now runs both test_loader.js (API existence) and test_ci_functional.js (API functionality) to ensure binaries are usable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces the manual package/release flow with automated publishing: - Tag push (v*) triggers: build → validate → npm publish → GitHub Release - Validates all 5 platform prebuilds before publishing - Uses NPM_TOKEN secret for npm authentication - Creates GitHub Release with per-platform tar.gz archives - Removes cleanup job (artifacts auto-expire) - Adds PUBLISHING.md with release instructions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrites the project guide to reflect the current shim-layer architecture. Includes clear step-by-step instructions for adding new API methods across all 4 layers (shim → C++ → JS → TS). Condensed from 333 to 131 lines while retaining all essential info. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/shim/) that wraps all ~95 Hamlib API calls with opaque handles, eliminating the MSVC/MinGW struct layout incompatibility that caused immediate crashes on Windowshamlib.cppto useshim_rig_*functions exclusively — no conditional compilation, all platforms use the same code pathbinding.gypby removing complex Hamlib path search logic, pthread dependency, and MinGW conditional compilationArchitecture
Test plan
🤖 Generated with Claude Code