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.
```
## 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)
- 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)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps")
# Options
option(ENABLE_TESTING "Build unit tests" ON)
# Platform flags
include(Platform)
include(Flags)
@@ -18,8 +21,10 @@ add_subdirectory(celrs)
add_subdirectory(tools)
# Testing
enable_testing()
add_subdirectory(tests)
if (ENABLE_TESTING)
enable_testing()
add_subdirectory(tests)
endif()
# IDE configuration
include(IDE)
+5 -8
View File
@@ -1,13 +1,10 @@
# celrs
A C23 project for interfacing with ELRS TX modules (e.g., BAYCK Nano Dual
Band) via serial USB using the CRSF (Crossfire Serial) protocol.
A C23 library and CLI tools for interfacing with ELRS TX modules (e.g.,
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)
using [Unity](https://github.com/ThrowTheSwitch/Unity) and
[CMock](https://github.com/ThrowTheSwitch/CMock).
All dependencies are fetched automatically via CMake `FetchContent` — no
All dependencies are fetched automatically via CMake `FetchContent`. No
manual installation required beyond the tools listed below.
## Requirements
@@ -18,7 +15,7 @@ manual installation required beyond the tools listed below.
| Ninja | Build backend |
| C23 compiler | GCC 14+, Clang 18+ |
| 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
+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)
target_include_directories(celrs_crsf PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_crsf PRIVATE c_std_23)
target_link_libraries(celrs_crsf PUBLIC celrs_serial)
target_include_directories(celcrsf PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celcrsf PRIVATE c_std_23)
target_link_libraries(celcrsf PUBLIC celserial)
add_library(cel::crsf ALIAS celcrsf)
# Platform-agnostic serial logic — calls cel_serial_platform_*();
# symbol resolved by celrs_serial_platform (or a mock in tests)
add_library(celrs_serial STATIC serial.c)
target_include_directories(celrs_serial PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_serial PRIVATE c_std_23)
# symbol resolved by celserial_platform (or a mock in tests)
add_library(celserial STATIC serial.c)
target_include_directories(celserial PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celserial PRIVATE c_std_23)
add_library(cel::serial ALIAS celserial)
# Real platform backend — linked into production binaries only
add_library(celrs_serial_platform STATIC)
target_include_directories(celrs_serial_platform PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_serial_platform PRIVATE c_std_23)
add_library(celserial_platform STATIC)
target_include_directories(celserial_platform PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celserial_platform PRIVATE c_std_23)
if (IS_WINDOWS)
target_sources(celrs_serial_platform PRIVATE platform/serial_win.c)
target_link_libraries(celrs_serial_platform PRIVATE advapi32 setupapi)
target_sources(celserial_platform PRIVATE platform/serial_win.c)
target_link_libraries(celserial_platform PRIVATE advapi32 setupapi)
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()
# Level-filtering logger — calls log_write(); symbol resolved by the final binary
add_library(celrs_logger STATIC logger.c)
target_include_directories(celrs_logger PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_logger PRIVATE c_std_23)
add_library(cellogger STATIC logger.c)
target_include_directories(cellogger PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(cellogger PRIVATE c_std_23)
add_library(cel::logger ALIAS cellogger)
# Real log_write implementation — linked into production binaries only
add_library(celrs_log_write STATIC log_write.c)
target_include_directories(celrs_log_write PUBLIC "${CMAKE_SOURCE_DIR}")
target_compile_features(celrs_log_write PRIVATE c_std_23)
add_library(cellog STATIC log_write.c)
target_include_directories(cellog PUBLIC "${CMAKE_SOURCE_DIR}")
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
add_executable(test_crsf test_crsf.c)
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)
add_test(NAME test_crsf COMMAND test_crsf)
list(APPEND TEST_TARGETS test_crsf)
@@ -42,7 +42,7 @@ list(APPEND TEST_TARGETS test_crsf)
# CRSF stream tests
add_executable(test_crsf_stream test_crsf_stream.c)
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)
add_test(NAME test_crsf_stream COMMAND test_crsf_stream)
list(APPEND TEST_TARGETS test_crsf_stream)
@@ -50,7 +50,7 @@ list(APPEND TEST_TARGETS test_crsf_stream)
# CRSF telemetry tests
add_executable(test_crsf_telemetry test_crsf_telemetry.c)
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)
add_test(NAME test_crsf_telemetry COMMAND 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
add_executable(test_crsf_param test_crsf_param.c)
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)
cmock_generate_mock(test_crsf_param "${CMAKE_SOURCE_DIR}/celrs/platform/serial_internal.h")
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)
add_executable(test_serial test_serial.c)
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)
cmock_generate_mock(test_serial "${CMAKE_SOURCE_DIR}/celrs/platform/serial_internal.h")
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
add_executable(test_logger test_logger.c)
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)
cmock_generate_mock(test_logger "${CMAKE_SOURCE_DIR}/celrs/log_write.h")
add_test(NAME test_logger COMMAND test_logger)
+1 -2
View File
@@ -1,5 +1,4 @@
add_executable(telemetry telemetry.c)
target_include_directories(telemetry PRIVATE "${CMAKE_SOURCE_DIR}")
target_compile_features(telemetry PRIVATE c_std_23)
target_link_libraries(telemetry PRIVATE celrs_crsf celrs_serial
celrs_serial_platform celrs_logger celrs_log_write)
target_link_libraries(telemetry PRIVATE cel::cel celserial_platform)