diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 41f45a4..7cc4886 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,23 +23,26 @@ jobs: - name: Install AVR toolchain run: | sudo apt-get update - sudo apt-get install -y --no-install-recommends gcc-avr avr-libc binutils-avr + sudo apt-get install -y --no-install-recommends gcc-avr avr-libc binutils-avr make - name: Toolchain versions run: | avr-gcc --version | head -1 avr-g++ --version | head -1 dpkg -s avr-libc | grep '^Version' + make --version | head -1 - name: Compile each .cpp standalone (-c, mmcu=${{ matrix.mcu }}) run: | set -e shopt -s nullglob for f in AVR++/*.cpp; do - # BDShot.cpp references `BDShotConfig::Debug::Pin` which the - # consumer is expected to declare. Can't compile standalone. + # BDShot.cpp is not a standalone translation unit — it's + # `#include`d by the consumer (along with an explicit template + # instantiation, per the README). Exercised separately below + # via tests/bdshot_compile_test.cpp. case "$f" in - AVR++/BDShot.cpp) echo "::notice::skipping $f (needs user config)"; continue;; + AVR++/BDShot.cpp) echo "::notice::skipping $f (intended to be included, not compiled standalone)"; continue;; esac echo "::group::$f" avr-g++ -c "$f" -o /dev/null \ @@ -71,3 +74,18 @@ jobs: -I . \ -DF_CPU=16000000UL \ -Wall + + - name: Compile BDShot test (user-facing #include pattern) + run: | + avr-g++ -c tests/bdshot_compile_test.cpp -o /dev/null \ + -mmcu=${{ matrix.mcu }} \ + -std=gnu++17 \ + -fno-exceptions \ + -funsigned-char \ + -funsigned-bitfields \ + -fpack-struct \ + -fshort-enums \ + -Os \ + -I . \ + -DF_CPU=16000000UL \ + -Wall diff --git a/tests/bdshot_compile_test.cpp b/tests/bdshot_compile_test.cpp new file mode 100644 index 0000000..7a7b7ce --- /dev/null +++ b/tests/bdshot_compile_test.cpp @@ -0,0 +1,20 @@ +// CI smoke test for the BDShot driver. BDShot.cpp is intended to be +// `#include`d by the consumer (yes, a .cpp file) — it has no separate +// translation unit. To exercise it in CI we follow the README pattern: the +// consumer includes the .cpp, declares an explicit template instantiation +// for the pin combination they want, then references the type. +// +// BDShotConfig::Debug::Pin defaults to AVR::Output which is +// the sentinel "dummy pin" (Pin 8 → no-op IOpin), so no stub config is +// required here. + +#include + +template class AVR::DShot::BDShot; + +namespace { +[[maybe_unused]] inline void touch() { + using ESC = AVR::DShot::BDShot; + ESC::init(); +} +} // namespace