From 5081002ba69450e58c0112fd0fd1415a5f4f55a3 Mon Sep 17 00:00:00 2001 From: odudex Date: Mon, 6 Jul 2026 16:48:15 -0300 Subject: [PATCH 1/2] ci: Build ESP-IDF smoke app on v6.0.2 (esp32p4) alongside v5.5.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IDF 6.0 ships mbedTLS v4, which moved the crypto headers under mbedtls/private/. The repo-root component CMakeLists already requires the Kern-style mbedtls_compat shim on IDF >= 6; the CI smoke app now mirrors that conditional and vendors a minimal header-only copy of the shim (the sha256 redirect only — the single mbedTLS API cUR uses). mbedtls_sha256() itself still exists in v4, so no source file is needed. The esp-idf job becomes a two-leg matrix: v5.5.4/esp32 keeps covering the plain-mbedtls path, v6.0.2/esp32p4 (Kern's target) exercises the shim path. Verified locally against ESP-IDF v6.0.2 for esp32p4: the smoke app builds and links, with cUR resolving mbedtls_sha256 through the shim's include path. --- .github/workflows/test.yml | 18 ++++++++++++++---- .../components/cUR/CMakeLists.txt | 11 ++++++++++- .../components/mbedtls_compat/CMakeLists.txt | 10 ++++++++++ .../components/mbedtls_compat/mbedtls/sha256.h | 5 +++++ 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 tests/esp-idf-smoke/components/mbedtls_compat/CMakeLists.txt create mode 100644 tests/esp-idf-smoke/components/mbedtls_compat/mbedtls/sha256.h diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b4d14b..ef8a16c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,13 +31,23 @@ jobs: run: make test esp-idf: - name: ESP-IDF component build + name: ESP-IDF ${{ matrix.idf }} build (${{ matrix.target }}) runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # v5.5.x uses plain mbedtls; v6.x (mbedTLS v4) exercises the + # mbedtls_compat shim path. esp32p4 is Kern's target on IDF 6. + include: + - idf: v5.5.4 + target: esp32 + - idf: v6.0.2 + target: esp32p4 steps: - uses: actions/checkout@v4 - - name: Build smoke-test app for esp32 + - name: Build smoke-test app uses: espressif/esp-idf-ci-action@v1 with: - esp_idf_version: v5.5.4 - target: esp32 + esp_idf_version: ${{ matrix.idf }} + target: ${{ matrix.target }} path: 'tests/esp-idf-smoke' diff --git a/tests/esp-idf-smoke/components/cUR/CMakeLists.txt b/tests/esp-idf-smoke/components/cUR/CMakeLists.txt index c41f271..4c0573e 100644 --- a/tests/esp-idf-smoke/components/cUR/CMakeLists.txt +++ b/tests/esp-idf-smoke/components/cUR/CMakeLists.txt @@ -11,10 +11,19 @@ file(GLOB CUR_SRCS "${CUR_REPO_ROOT}/src/types/*.c" ) +# Mirror the repo-root CMakeLists.txt: mbedTLS v4 (ESP-IDF >= 6.0) needs the +# mbedtls_compat header shim (vendored next to this component for the smoke +# build; real consumers like Kern bring their own). +if(IDF_VERSION_MAJOR GREATER_EQUAL 6) + set(CUR_SMOKE_REQUIRES mbedtls mbedtls_compat) +else() + set(CUR_SMOKE_REQUIRES mbedtls) +endif() + idf_component_register( SRCS ${CUR_SRCS} INCLUDE_DIRS "${CUR_REPO_ROOT}/src" - REQUIRES mbedtls + REQUIRES ${CUR_SMOKE_REQUIRES} ) target_compile_definitions(${COMPONENT_LIB} PUBLIC UR_USE_MBEDTLS_SHA256) diff --git a/tests/esp-idf-smoke/components/mbedtls_compat/CMakeLists.txt b/tests/esp-idf-smoke/components/mbedtls_compat/CMakeLists.txt new file mode 100644 index 0000000..bf60e76 --- /dev/null +++ b/tests/esp-idf-smoke/components/mbedtls_compat/CMakeLists.txt @@ -0,0 +1,10 @@ +# Minimal vendored copy of the Kern project's mbedtls_compat shim, trimmed +# to SHA-256 (the only mbedTLS API cUR uses). mbedTLS v4 (ESP-IDF >= 6.0) +# moved the crypto headers from mbedtls/ to mbedtls/private/; this +# header-only component redirects #include so +# src/sha256/sha256_compat.h keeps working. Real consumers on IDF >= 6 +# (e.g. Kern) provide their own copy — see the repo-root CMakeLists.txt. +idf_component_register( + INCLUDE_DIRS "." + REQUIRES mbedtls +) diff --git a/tests/esp-idf-smoke/components/mbedtls_compat/mbedtls/sha256.h b/tests/esp-idf-smoke/components/mbedtls_compat/mbedtls/sha256.h new file mode 100644 index 0000000..a313b12 --- /dev/null +++ b/tests/esp-idf-smoke/components/mbedtls_compat/mbedtls/sha256.h @@ -0,0 +1,5 @@ +// Compatibility shim (vendored from Kern): mbedTLS v4 moved sha256.h to +// mbedtls/private/. MBEDTLS_ALLOW_PRIVATE_ACCESS keeps the context struct +// fields reachable through the private header. +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#include "mbedtls/private/sha256.h" From 4c834bda2b9065eaa2bda522030e61792d33dada Mon Sep 17 00:00:00 2001 From: odudex Date: Mon, 6 Jul 2026 17:01:13 -0300 Subject: [PATCH 2/2] fix: Hide modern module registration from the legacy K210 genhdr scan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The K210 MaixPy build generates genhdr/moduledefs.h by regex-scanning raw C sources for the registration macro, ignoring preprocessor conditionals. With 4ecccea's dual registration (2-arg modern form plus 3-arg legacy form under #if MICROPY_VERSION), the DOTALL 3-group pattern matched across the #else and emitted a mangled header ("#else after #else", "#if (bc_ur_module, MODULE_BC_UR_ENABLED)"), breaking the Krux Amigo firmware build. Register the modern branch through a UR_REGISTER_MODULE alias: the legacy raw-text scanner no longer matches that line and sees only the 3-arg form (its generated header is again identical in shape to the pre-4ecccea output), while modern MicroPython (>= 1.19, incl. 1.27) collects registrations from preprocessed source, where the alias has already expanded to the real 2-arg macro — the same token stream already verified on-device for 1.27. Verified by running Krux's own makemoduledefs.py against uUR.c (mangled before, clean after) and by preprocessing the modern branch with MICROPY_VERSION=1.27.0. Co-Authored-By: Claude Fable 5 --- uUR.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/uUR.c b/uUR.c index c2714f8..d3fd9e3 100644 --- a/uUR.c +++ b/uUR.c @@ -1026,8 +1026,18 @@ const mp_obj_module_t bc_ur_module = { // legacy form and fail to compile. MICROPY_VERSION is // (major << 16 | minor << 8 | micro); on builds too old to define it, the // expression evaluates to 0 and correctly selects the legacy 3-arg form. +// +// The modern branch registers through the UR_REGISTER_MODULE alias, not the +// macro's own name: the legacy MaixPy (K210) build generates +// genhdr/moduledefs.h by regex-scanning the RAW source for the macro name, +// ignoring preprocessor conditionals, and with two visible registrations the +// scan mangles the generated header ("#else after #else"). The alias keeps +// the modern line invisible to that scanner; modern builds collect +// registrations from PREPROCESSED source, where the alias has already +// expanded to the real macro. #if MICROPY_VERSION >= ((1 << 16) | (19 << 8)) // >= v1.19 -MP_REGISTER_MODULE(MP_QSTR_uUR, bc_ur_module); +#define UR_REGISTER_MODULE MP_REGISTER_MODULE +UR_REGISTER_MODULE(MP_QSTR_uUR, bc_ur_module); #else MP_REGISTER_MODULE(MP_QSTR_uUR, bc_ur_module, MODULE_BC_UR_ENABLED); #endif