Skip to content

build: add reusable CMake library target for downstream projects#236

Open
m-mcgowan wants to merge 6 commits intoblues:masterfrom
m-mcgowan:build/cmake-library-target
Open

build: add reusable CMake library target for downstream projects#236
m-mcgowan wants to merge 6 commits intoblues:masterfrom
m-mcgowan:build/cmake-library-target

Conversation

@m-mcgowan
Copy link
Contributor

@m-mcgowan m-mcgowan commented Mar 9, 2026

Adds a reusable CMake library target, so that downstream targets don't have to deal with note-c internals, and can opt-in to build the tests.

This builds on PR #225, since those fixes are needed to get a clean build on macOS.

Summary

  • Adds a note_c_lib static library target that downstream projects (e.g. note-posix) can consume via add_subdirectory and target_link_libraries, without pulling in the unit test harness, 32-bit cross-compile flags, or FFF interposition settings, which are specific to the tests.
  • Defaults NOTE_C_BUILD_TESTS to ON only when note-c is the top-level project (using PROJECT_IS_TOP_LEVEL), so subdirectory consumers skip tests automatically.
  • Bumps cmake_minimum_required from 3.20 to 3.21 for PROJECT_IS_TOP_LEVEL support.
  • Includes an integration test (test/integration/) that exercises the add_subdirectory workflow end-to-end.

Usage

  add_subdirectory(note-c)
  target_link_libraries(my_app PRIVATE note_c_lib)

The note_c_lib target carries the public include path, platform compile definitions (HAVE_STRLCPY, etc.), and all build options (NOTE_C_LOW_MEM, NOTE_C_SINGLE_PRECISION, etc.) — but none of the test-specific settings.

Test plan

  • Existing unit tests pass (Linux CI unchanged)
  • Integration test builds and passes (test/integration/)
  • Verified with https://github.com/zakoverflow/note-posix — pristine clone builds and passes all 13 tests on macOS using note_c_lib

Add conditional CMake configuration for macOS (APPLE):
- Skip -m32 and Linux-specific linker flags
- Define HAVE_STRLCPY/HAVE_STRLCAT (macOS provides these natively)
- Exclude n_str.c (strlcpy/strlcat bundled implementations)
- Suppress AppleClang-specific warnings in upstream code
- Use -flat_namespace for dylib and test executables to enable
FFF test fake symbol interposition

All changes are guarded by if(APPLE)/if(NOT APPLE) so Linux CI behavior is completely unchanged.
Use check_symbol_exists() to detect system-provided strlcpy/strlcat (macOS, *BSD) and conditionally exclude n_str.c and define HAVE_STRLCPY/ HAVE_STRLCAT guards. This avoids collisions with the platform's fortified string macros that prevented compilation on macOS.

Guard the 32-bit x86 compile/link flags behind a Linux x86 check instead of if(NOT APPLE), making the build portable to any non-x86 platform.

Suppress two AppleClang warnings-as-errors in upstream code (-Wstrict-prototypes, -Wunused-but-set-variable).

Add -Wl,-flat_namespace on macOS for both the library and test executables so FFF test fakes can interpose dylib symbols.
- n_ua.c: add void to NoteUserAgent() prototype to fix
-Wstrict-prototypes (empty parens means unspecified args in C)
- n_helpers.c: remove unused variables j and lastLengthCount that
triggered -Wunused-but-set-variable

With these fixes the -Wno-* suppressions added in the previous commit are no longer needed and are removed from CMakeLists.txt.
Adds a `run_macos_unit_tests` job that configures and builds note-c with tests on macos-latest. Tests are not run via ctest because FFF symbol interposition does not fully work on macOS — even with -flat_namespace, intra-library calls are resolved at link time and cannot be faked.
- Add `strlcpy` and `strlcat` to the libc dependency whitelist so the `check_libc_dependencies` job passes when `n_str.c` is excluded on
  systems that provide these functions natively (glibc 2.38+).
- Only add `n_str.c` to the lcov coverage exclude list when the file is actually compiled, avoiding an lcov error on unused patterns.
Add a clean note_c_lib static library target that downstream projects (e.g. note-posix) can consume via add_subdirectory + target_link_libraries without pulling in the unit test harness, 32-bit cross-compile flags, or FFF interposition settings.

- Bump cmake_minimum_required to 3.21 for `PROJECT_IS_TOP_LEVEL`
- Default `NOTE_C_BUILD_TESTS` to ON only when note-c is the top-level project; OFF when included as a subdirectory
- Move the existing note_c shared library (with -Werror, 32-bit flags, NOTE_C_TEST, etc.) inside the NOTE_C_BUILD_TESTS guard
- Add test/integration/ with a standalone CMake project that verifies `note_c_lib` links correctly via `add_subdirectory`
@m-mcgowan m-mcgowan force-pushed the build/cmake-library-target branch from a2f10d9 to 6dedcda Compare March 9, 2026 19:30
@zfields
Copy link
Contributor

zfields commented Mar 11, 2026

Pretty cool! 🌟

I'm tending a dumpster fire at the moment 🔥, but I am excited to check this one out! 😎

Cheers!

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.

2 participants