diff --git a/pc/CMakeLists.txt b/pc/CMakeLists.txt index 1a7fec227e..d57263cae8 100644 --- a/pc/CMakeLists.txt +++ b/pc/CMakeLists.txt @@ -18,6 +18,13 @@ set(CMAKE_CXX_STANDARD 23) # needed here. find_package(espp REQUIRED) +# Every test here links the WHOLE espp::espp archive (below), so the full espp +# package — headers AND compiled objects like Logger — is guaranteed available. +# Declare that to the tests explicitly: pc/tests/odrive_native_golden.cpp keys +# its espp::OdriveNative wrapper section off this (the minimal interop-harness +# build of the same file gets no define and falls back to header detection). +add_compile_definitions(ODRIVE_GOLDEN_HAS_ESPP_LIB=1) + MACRO(GEN_TESTS curdir) # get test files FILE(GLOB tests RELATIVE ${curdir} ${curdir}/tests/*.cpp) diff --git a/pc/tests/odrive_native_golden.cpp b/pc/tests/odrive_native_golden.cpp index 3a8fe2d77b..89cfbb1d8f 100644 --- a/pc/tests/odrive_native_golden.cpp +++ b/pc/tests/odrive_native_golden.cpp @@ -4,9 +4,14 @@ // round-trip, all verified against the fw-v0.5.1 reference (and proven end-to-end // by the serial-loopback interop harness in components/odrive_native/interop). // -// Built by the pc harness against the installed espp package: odrive_native is -// part of the x-platform espp lib, so its headers come from the espp::espp -// target like every other test here. Exits 0 when every golden matches. +// Built two ways: +// - by the pc harness against the installed espp package (full espp::espp +// target, so the espp::OdriveNative wrapper section below also runs); +// - by the interop harness (components/odrive_native/interop/run_interop.sh) +// with ONLY `c++ -std=c++20 -I components/odrive_native/include` — no espp +// lib, so the wrapper section (which needs base_component/logger/fmt and +// the compiled Logger) is compiled out via the __has_include guard. +// Exits 0 when every golden matches. #include #include @@ -18,7 +23,24 @@ #include "detail/odrive_native_core.hpp" #include "detail/odrive_native_stream.hpp" + +// The espp::OdriveNative wrapper is only testable when the full espp package +// (base_component + logger + fmt headers AND the compiled Logger) is on the +// include/link path — i.e. the pc build, whose harness defines +// ODRIVE_GOLDEN_HAS_ESPP_LIB=1 (see ../CMakeLists.txt) because it links the +// whole espp::espp archive. When the build system says nothing (e.g. a bare +// compile of this file), fall back to header detection; the macro is ALWAYS +// defined to 0 or 1 so `#if` is -Wundef-clean. +#if !defined(ODRIVE_GOLDEN_HAS_ESPP_LIB) +#if defined(__has_include) && __has_include("base_component.hpp") +#define ODRIVE_GOLDEN_HAS_ESPP_LIB 1 +#else +#define ODRIVE_GOLDEN_HAS_ESPP_LIB 0 +#endif +#endif +#if ODRIVE_GOLDEN_HAS_ESPP_LIB #include "odrive_native.hpp" +#endif using espp::detail::kProtocolVersion; using espp::detail::odrive_crc16; @@ -132,7 +154,9 @@ static void golden_packet_roundtrip() { // The espp::OdriveNative wrapper (BaseComponent + the core) is what the lib // exposes; exercise it through the same read/write path to prove the -// x-platform packaging end-to-end (not just the detail/ headers). +// x-platform packaging end-to-end (not just the detail/ headers). Only built +// when the full espp package is available (see the guard at the top). +#if ODRIVE_GOLDEN_HAS_ESPP_LIB static void lib_wrapper_roundtrip() { std::printf("lib_wrapper_roundtrip\n"); espp::OdriveNative dev(espp::OdriveNative::Config{.log_level = espp::Logger::Verbosity::WARN}); @@ -178,13 +202,18 @@ static void lib_wrapper_roundtrip() { CHECK(rb == wrote); } } +#endif // ODRIVE_GOLDEN_HAS_ESPP_LIB int main() { golden_crc8(); golden_crc16(); golden_frame(); golden_packet_roundtrip(); +#if ODRIVE_GOLDEN_HAS_ESPP_LIB lib_wrapper_roundtrip(); +#else + std::printf("lib_wrapper_roundtrip skipped (minimal build without the espp lib)\n"); +#endif if (g_failures == 0) { std::printf("\nODRIVE_NATIVE GOLDEN: ALL PASSED\n"); return 0;