Compare commits

...

2 Commits

Author SHA1 Message Date
portersky 23050d983e docs: add tag release workflow to AGENTS.md 2026-06-15 00:41:53 +02:00
portersky 974b33e827 chore: rename targets and add ENABLE_TESTING option
Rename library targets from celrs_* to cel* (celcrsf, celserial,
cellogger, cellog) and add cel:: namespace aliases. Add cel::cel
umbrella target that links all core libraries.

Add ENABLE_TESTING option (default ON) to gate Unity/CMock fetch
and test targets for downstream consumers.
2026-06-15 00:39:25 +02:00
6 changed files with 87 additions and 38 deletions
+39
View File
@@ -105,6 +105,45 @@ Implement CRC8-CCITT (poly 0x07) for CRSF frame validation.
Added unit tests for empty, single-byte, and known-value cases. Added unit tests for empty, single-byte, and known-value cases.
``` ```
## Tag Releases
Use annotated tags for releases. Write the release notes to a temporary
file, then use it as the tag message. Do **not** commit the release
notes file.
Write release notes:
```sh
cat > RELEASES.md << 'EOF'
# Releases
## 0.1.0 (2026-06-15)
Initial release. Windows-only support.
### Library (`celrs`)
- **CRSF protocol** ...
EOF
```
Create the annotated tag:
```sh
git tag -a v0.1.0 -F RELEASES.md
```
Verify:
```sh
git show v0.1.0
```
Remove the temporary file:
```sh
rm RELEASES.md
```
Release notes follow the same Markdown rules as `AGENTS.md` (80-column
wrap, no em dashes, etc.). Version format is `v<major>.<minor>.<patch>`.
## Documentation (Markdown) ## Documentation (Markdown)
- Wrap normal text and lists at **max 80 columns** (for readability in - Wrap normal text and lists at **max 80 columns** (for readability in
+7 -2
View File
@@ -5,6 +5,9 @@ project(celrs VERSION 0.1.0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps")
# Options
option(ENABLE_TESTING "Build unit tests" ON)
# Platform flags # Platform flags
include(Platform) include(Platform)
include(Flags) include(Flags)
@@ -18,8 +21,10 @@ add_subdirectory(celrs)
add_subdirectory(tools) add_subdirectory(tools)
# Testing # Testing
enable_testing() if (ENABLE_TESTING)
add_subdirectory(tests) enable_testing()
add_subdirectory(tests)
endif()
# IDE configuration # IDE configuration
include(IDE) include(IDE)
+5 -8
View File
@@ -1,13 +1,10 @@
# celrs # celrs
A C23 project for interfacing with ELRS TX modules (e.g., BAYCK Nano Dual A C23 library and CLI tools for interfacing with ELRS TX modules (e.g.,
Band) via serial USB using the CRSF (Crossfire Serial) protocol. BAYCK Nano Dual Band) via serial USB using the CRSF (Crossfire Serial)
protocol.
Built on the same TDD foundation as [ctdd](https://github.com/PorterSky/ctdd) All dependencies are fetched automatically via CMake `FetchContent`. No
using [Unity](https://github.com/ThrowTheSwitch/Unity) and
[CMock](https://github.com/ThrowTheSwitch/CMock).
All dependencies are fetched automatically via CMake `FetchContent` — no
manual installation required beyond the tools listed below. manual installation required beyond the tools listed below.
## Requirements ## Requirements
@@ -18,7 +15,7 @@ manual installation required beyond the tools listed below.
| Ninja | Build backend | | Ninja | Build backend |
| C23 compiler | GCC 14+, Clang 18+ | | C23 compiler | GCC 14+, Clang 18+ |
| Ruby ≥ 3.0 | CMock mock generation | | Ruby ≥ 3.0 | CMock mock generation |
| gcovr ≥ 6.0 | Coverage reports optional (`uv tool install gcovr`) | | gcovr ≥ 6.0 | Coverage reports - optional (`uv tool install gcovr`) |
## Build ## Build
+29 -20
View File
@@ -1,32 +1,41 @@
add_library(celrs_crsf STATIC crsf.c crsf_telemetry.c crsf_stream.c add_library(celcrsf STATIC crsf.c crsf_telemetry.c crsf_stream.c
crsf_param.c) crsf_param.c)
target_include_directories(celrs_crsf PUBLIC "${CMAKE_SOURCE_DIR}") target_include_directories(celcrsf PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_crsf PRIVATE c_std_23) target_compile_features(celcrsf PRIVATE c_std_23)
target_link_libraries(celrs_crsf PUBLIC celrs_serial) target_link_libraries(celcrsf PUBLIC celserial)
add_library(cel::crsf ALIAS celcrsf)
# Platform-agnostic serial logic — calls cel_serial_platform_*(); # Platform-agnostic serial logic — calls cel_serial_platform_*();
# symbol resolved by celrs_serial_platform (or a mock in tests) # symbol resolved by celserial_platform (or a mock in tests)
add_library(celrs_serial STATIC serial.c) add_library(celserial STATIC serial.c)
target_include_directories(celrs_serial PUBLIC "${CMAKE_SOURCE_DIR}") target_include_directories(celserial PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_serial PRIVATE c_std_23) target_compile_features(celserial PRIVATE c_std_23)
add_library(cel::serial ALIAS celserial)
# Real platform backend — linked into production binaries only # Real platform backend — linked into production binaries only
add_library(celrs_serial_platform STATIC) add_library(celserial_platform STATIC)
target_include_directories(celrs_serial_platform PUBLIC "${CMAKE_SOURCE_DIR}") target_include_directories(celserial_platform PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_serial_platform PRIVATE c_std_23) target_compile_features(celserial_platform PRIVATE c_std_23)
if (IS_WINDOWS) if (IS_WINDOWS)
target_sources(celrs_serial_platform PRIVATE platform/serial_win.c) target_sources(celserial_platform PRIVATE platform/serial_win.c)
target_link_libraries(celrs_serial_platform PRIVATE advapi32 setupapi) target_link_libraries(celserial_platform PRIVATE advapi32 setupapi)
elseif(IS_LINUX OR IS_MACOS) elseif(IS_LINUX OR IS_MACOS)
target_sources(celrs_serial_platform PRIVATE platform/serial_posix.c) target_sources(celserial_platform PRIVATE platform/serial_posix.c)
endif() endif()
# Level-filtering logger — calls log_write(); symbol resolved by the final binary # Level-filtering logger — calls log_write(); symbol resolved by the final binary
add_library(celrs_logger STATIC logger.c) add_library(cellogger STATIC logger.c)
target_include_directories(celrs_logger PUBLIC "${CMAKE_SOURCE_DIR}") target_include_directories(cellogger PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_logger PRIVATE c_std_23) target_compile_features(cellogger PRIVATE c_std_23)
add_library(cel::logger ALIAS cellogger)
# Real log_write implementation — linked into production binaries only # Real log_write implementation — linked into production binaries only
add_library(celrs_log_write STATIC log_write.c) add_library(cellog STATIC log_write.c)
target_include_directories(celrs_log_write PUBLIC "${CMAKE_SOURCE_DIR}") target_include_directories(cellog PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_log_write PRIVATE c_std_23) target_compile_features(cellog PRIVATE c_std_23)
add_library(cel::log ALIAS cellog)
# Umbrella target — links all celrs libraries
add_library(cel INTERFACE)
target_link_libraries(cel INTERFACE celcrsf celserial cellogger cellog)
add_library(cel::cel ALIAS cel)
+6 -6
View File
@@ -34,7 +34,7 @@ set(TEST_TARGETS "")
# CRSF tests — pure functions (CRC, parse, build), no mock needed # CRSF tests — pure functions (CRC, parse, build), no mock needed
add_executable(test_crsf test_crsf.c) add_executable(test_crsf test_crsf.c)
target_include_directories(test_crsf PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(test_crsf PRIVATE "${CMAKE_SOURCE_DIR}")
target_link_libraries(test_crsf PRIVATE celrs_crsf Unity::Unity) target_link_libraries(test_crsf PRIVATE celcrsf Unity::Unity)
target_compile_features(test_crsf PRIVATE c_std_23) target_compile_features(test_crsf PRIVATE c_std_23)
add_test(NAME test_crsf COMMAND test_crsf) add_test(NAME test_crsf COMMAND test_crsf)
list(APPEND TEST_TARGETS test_crsf) list(APPEND TEST_TARGETS test_crsf)
@@ -42,7 +42,7 @@ list(APPEND TEST_TARGETS test_crsf)
# CRSF stream tests # CRSF stream tests
add_executable(test_crsf_stream test_crsf_stream.c) add_executable(test_crsf_stream test_crsf_stream.c)
target_include_directories(test_crsf_stream PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(test_crsf_stream PRIVATE "${CMAKE_SOURCE_DIR}")
target_link_libraries(test_crsf_stream PRIVATE celrs_crsf Unity::Unity) target_link_libraries(test_crsf_stream PRIVATE celcrsf Unity::Unity)
target_compile_features(test_crsf_stream PRIVATE c_std_23) target_compile_features(test_crsf_stream PRIVATE c_std_23)
add_test(NAME test_crsf_stream COMMAND test_crsf_stream) add_test(NAME test_crsf_stream COMMAND test_crsf_stream)
list(APPEND TEST_TARGETS test_crsf_stream) list(APPEND TEST_TARGETS test_crsf_stream)
@@ -50,7 +50,7 @@ list(APPEND TEST_TARGETS test_crsf_stream)
# CRSF telemetry tests # CRSF telemetry tests
add_executable(test_crsf_telemetry test_crsf_telemetry.c) add_executable(test_crsf_telemetry test_crsf_telemetry.c)
target_include_directories(test_crsf_telemetry PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(test_crsf_telemetry PRIVATE "${CMAKE_SOURCE_DIR}")
target_link_libraries(test_crsf_telemetry PRIVATE celrs_crsf Unity::Unity) target_link_libraries(test_crsf_telemetry PRIVATE celcrsf Unity::Unity)
target_compile_features(test_crsf_telemetry PRIVATE c_std_23) target_compile_features(test_crsf_telemetry PRIVATE c_std_23)
add_test(NAME test_crsf_telemetry COMMAND test_crsf_telemetry) add_test(NAME test_crsf_telemetry COMMAND test_crsf_telemetry)
list(APPEND TEST_TARGETS test_crsf_telemetry) list(APPEND TEST_TARGETS test_crsf_telemetry)
@@ -58,7 +58,7 @@ list(APPEND TEST_TARGETS test_crsf_telemetry)
# CRSF param tests — mocks serial for write/ping/read # CRSF param tests — mocks serial for write/ping/read
add_executable(test_crsf_param test_crsf_param.c) add_executable(test_crsf_param test_crsf_param.c)
target_include_directories(test_crsf_param PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(test_crsf_param PRIVATE "${CMAKE_SOURCE_DIR}")
target_link_libraries(test_crsf_param PRIVATE celrs_crsf celrs_serial Unity::Unity CMock::CMock) target_link_libraries(test_crsf_param PRIVATE celcrsf celserial Unity::Unity CMock::CMock)
target_compile_features(test_crsf_param PRIVATE c_std_23) target_compile_features(test_crsf_param PRIVATE c_std_23)
cmock_generate_mock(test_crsf_param "${CMAKE_SOURCE_DIR}/celrs/platform/serial_internal.h") cmock_generate_mock(test_crsf_param "${CMAKE_SOURCE_DIR}/celrs/platform/serial_internal.h")
add_test(NAME test_crsf_param COMMAND test_crsf_param) add_test(NAME test_crsf_param COMMAND test_crsf_param)
@@ -67,7 +67,7 @@ list(APPEND TEST_TARGETS test_crsf_param)
# Serial tests — mocks the platform backend (serial_internal.h) # Serial tests — mocks the platform backend (serial_internal.h)
add_executable(test_serial test_serial.c) add_executable(test_serial test_serial.c)
target_include_directories(test_serial PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(test_serial PRIVATE "${CMAKE_SOURCE_DIR}")
target_link_libraries(test_serial PRIVATE celrs_serial Unity::Unity CMock::CMock) target_link_libraries(test_serial PRIVATE celserial Unity::Unity CMock::CMock)
target_compile_features(test_serial PRIVATE c_std_23) target_compile_features(test_serial PRIVATE c_std_23)
cmock_generate_mock(test_serial "${CMAKE_SOURCE_DIR}/celrs/platform/serial_internal.h") cmock_generate_mock(test_serial "${CMAKE_SOURCE_DIR}/celrs/platform/serial_internal.h")
add_test(NAME test_serial COMMAND test_serial) add_test(NAME test_serial COMMAND test_serial)
@@ -76,7 +76,7 @@ list(APPEND TEST_TARGETS test_serial)
# Logger tests — mocks log_write.h so output calls are intercepted # Logger tests — mocks log_write.h so output calls are intercepted
add_executable(test_logger test_logger.c) add_executable(test_logger test_logger.c)
target_include_directories(test_logger PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(test_logger PRIVATE "${CMAKE_SOURCE_DIR}")
target_link_libraries(test_logger PRIVATE celrs_logger Unity::Unity CMock::CMock) target_link_libraries(test_logger PRIVATE cellogger Unity::Unity CMock::CMock)
target_compile_features(test_logger PRIVATE c_std_23) target_compile_features(test_logger PRIVATE c_std_23)
cmock_generate_mock(test_logger "${CMAKE_SOURCE_DIR}/celrs/log_write.h") cmock_generate_mock(test_logger "${CMAKE_SOURCE_DIR}/celrs/log_write.h")
add_test(NAME test_logger COMMAND test_logger) add_test(NAME test_logger COMMAND test_logger)
+1 -2
View File
@@ -1,5 +1,4 @@
add_executable(telemetry telemetry.c) add_executable(telemetry telemetry.c)
target_include_directories(telemetry PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(telemetry PRIVATE "${CMAKE_SOURCE_DIR}")
target_compile_features(telemetry PRIVATE c_std_23) target_compile_features(telemetry PRIVATE c_std_23)
target_link_libraries(telemetry PRIVATE celrs_crsf celrs_serial target_link_libraries(telemetry PRIVATE cel::cel celserial_platform)
celrs_serial_platform celrs_logger celrs_log_write)