From 71d85bff79632ce36fcd6aa01e3c6c0be0cadd75 Mon Sep 17 00:00:00 2001 From: Paul Abbott Date: Tue, 30 Jun 2026 15:05:47 -0400 Subject: [PATCH] feat(builder): add per-MCU CMSIS PAL + CMSIS-Core to include path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PlatformIO Arduino builder only put the core dir and the selected board-pins variant (variants/) on CPPPATH. But the vendor CMSIS device header (e.g. LPC845.h) is a chip-level artifact that lives in variants//, which for most boards is a *different* directory than the pins variant (board lpc845brk selects variants/lpc845brk/, while the PAL ships in variants/lpc845/). As a result, code that includes the vendor device header () failed with "No such file or directory", and the transitively-included CMSIS-Core headers (core_cm0plus.h, cmsis_gcc.h) — which live at the framework root in CMSIS/ — were also missing. Add variants// and CMSIS/ to CPPPATH when they exist, so any board on a given MCU can consume the vendor device header regardless of which pins variant it selects. Both additions are guarded by os.path.isdir and the MCU dir is skipped when it coincides with the selected variant, so boards/frameworks without this layout are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) --- builder/frameworks/arduino.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 0041a84..41621ec 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -55,6 +55,19 @@ VARIANT_DIR = os.path.join(FRAMEWORK_DIR, "variants", VARIANT) LIBRARIES_DIR = os.path.join(FRAMEWORK_DIR, "libraries") +# The CMSIS device PAL (LPC845.h / system_LPC845.h, LPC804.h / ...) is a +# chip-level artifact keyed on build.mcu, not on the board-pins variant. It +# lives in variants//, which is usually a *different* directory than the +# selected board variant (e.g. mcu=lpc845 ships the PAL in variants/lpc845/ +# while board lpc845brk selects variants/lpc845brk/). Add it to CPPPATH so a +# board on a given MCU can #include the vendor device header regardless of +# which pins variant it selects. CMSIS-Core (core_cm0plus.h, cmsis_gcc.h, ...) +# is pulled in transitively by the device header and ships once at the +# framework root in CMSIS/. +MCU = board.get("build.mcu", "") +CMSIS_DIR = os.path.join(FRAMEWORK_DIR, "variants", MCU) if MCU else "" +CMSIS_CORE_DIR = os.path.join(FRAMEWORK_DIR, "CMSIS") + assert os.path.isdir(CORE_DIR), ( "Arduino core directory missing: %s" % CORE_DIR) assert os.path.isdir(VARIANT_DIR), ( @@ -102,7 +115,13 @@ CPPPATH=[ CORE_DIR, VARIANT_DIR, - ], + ] + ( + [CMSIS_DIR] + if CMSIS_DIR and CMSIS_DIR != VARIANT_DIR and os.path.isdir(CMSIS_DIR) + else [] + ) + ( + [CMSIS_CORE_DIR] if os.path.isdir(CMSIS_CORE_DIR) else [] + ), LINKFLAGS=machine_flags + [ "-Os",