Skip to content

Commit 99984d4

Browse files
emraineyCopilot
andcommitted
Fixes to CI and scripting to support
What's Wrong: * CI broke due to capitalization issue How Was it Fixed (if not obvious): * fixed case What side effects does this have (could be none): * Added script to test all presets and ci builds locally * Updated README for scripts and correctness. Which builds did you run to make sure they build? [x] arm-none-eabi-gcc Cortex M4 [x] arm-none-eabi-gcc Cortex M7 [x] (Apple) Native Clang [x] (Apple) Homebrew GCC (path breaks) [x] (Apple) Homebrew LLVM How Do We Know and Can Show It's Fixed: * Builds Which Unittest Series did you Check? [x] (Apple) Native Clang [ ] (Apple) Homebrew GCC [x] (Apple) Homebrew LLVM Did this affect any on-target builds? If so which were tested? [X] STM32F407VE board [X] STM32H753ZI board Co-authored-by: Copilot <copilot@github.com>
1 parent c731f84 commit 99984d4

9 files changed

Lines changed: 314 additions & 51 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
# Ignore Build Output
3535
build/
3636

37+
# Ignore Python virtual environments
38+
venv/
39+
.venv/
40+
3741
$ Ignore Mac OSX Files
3842
.DS_Store
3943
._.DS_Store

README.md

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,45 +75,97 @@ Renode is a (not nearly complete enough) emulation of the Cortex M series and it
7575
* <https://interrupt.memfault.com/blog/intro-to-renode>
7676
* <https://zephyr-dashboard.renode.io/renodepedia/boards/segger_trb_stm32f407/?view=hardware&demo=Hello_World>
7777

78-
## QEMU
78+
## Building
7979

80-
TBD
80+
Visual Studio Code should be able to run this and identify the presets configuration.
8181

82-
## Building
82+
Be sure to configure the CMake Environment variables to point to your arm-none-eabi-gcc toolchain. If you installed the Arm GNU Toolchain via the Mac PKG, the path should be `/Applications/ArmGNUToolchain/13.2.rel1/arm-none-eabi/bin` but it may be different if you installed it differently or on a different OS.
8383

84-
Visual Studio Code should be able to run this and identify the presets configuration. However you can also use the command line.
84+
### Command Line
85+
86+
However you can also use the command line.
8587

8688
```bash
8789
# After installing arm-none-eabi-gcc via mac pkg
88-
$ export PATH=$PATH:/Application/ARM/bin
90+
$ export PATH=${PATH}:/Applications/ArmGNUToolchain/13.2.rel1/arm-none-eabi/bin
8991
$ cmake --list-presets
9092
Available configure presets:
9193

92-
"cortex-gcc-arm-none-eabi-10" - GCC ARM None EABI 10 for Cortex-M
93-
"cortex-gcc-arm-none-eabi-11" - GCC ARM None EABI 11 for Cortex-M
94-
"cortex-gcc-arm-none-eabi-12" - GCC ARM None EABI 12 for Cortex-M
95-
"cortex-gcc-arm-none-eabi-13" - GCC ARM None EABI 13 for Cortex-M
96-
"native-gcc-11" - Homebrew GCC 11
97-
"native-gcc-12" - Homebrew GCC 12
98-
"native-gcc-13" - Homebrew GCC 13
99-
"native-llvm-19" - LLVM 19.1.7_1
100-
"native-clang" - Native Clang Toolchain
101-
$ cmake --preset cortex-gcc-arm-none-eabi-13 -B build/stm32-gcc-arm-none-eabi-13 -S .
102-
$ cmake --build build/cortex-gcc-arm-none-eabi-13
94+
"on-host" - Host Build
95+
"cortex-m4-gcc-arm-none-eabi" - cortex-m4
96+
"cortex-m7-gcc-arm-none-eabi" - cortex-m7
97+
"cortex-m4-gcc-arm-none-eabi-ci" - cortex-m4 (ci)
98+
"cortex-m7-gcc-arm-none-eabi-ci" - cortex-m7 (ci)
99+
"native-gcc" - Native GCC Toolchain
100+
"native-clang" - Native Clang Toolchain
101+
"native-llvm" - Native LLVM Toolchain (Homebrew LLVM potentially)
102+
$ cmake --preset cortex-m4-gcc-arm-none-eabi
103+
$ cmake --build --preset build-cortex-m4-gcc-arm-none-eabi
103104
# Or Run the Whole Workflow
104105
$ cmake --workflow --list-presets
105106
Available workflow presets:
106107

107-
"on-target-gcc-10"
108-
"on-target-gcc-11"
109-
"on-target-gcc-12"
110-
"on-target-gcc-13"
111-
"unit-tests-gcc-11"
112-
"unit-tests-gcc-12"
113-
"unit-tests-gcc-13"
114-
"unit-tests-llvm-19"
115-
"unit-tests-clang"
116-
$ cmake --workflow --preset unit-tests-clang"
108+
"on-target-cortex-m4-gcc-arm-none-eabi"
109+
"on-target-cortex-m7-gcc-arm-none-eabi"
110+
"on-target-cortex-m4-gcc-arm-none-eabi-ci"
111+
"on-target-cortex-m7-gcc-arm-none-eabi-ci"
112+
"on-host-native-gcc"
113+
"on-host-native-clang"
114+
"on-host-native-llvm"
115+
$ cmake --workflow --preset on-host-native-clang
116+
```
117+
118+
### Distributed Builds (distcc)
119+
120+
The on-target presets (`cortex-m4-gcc-arm-none-eabi`, `cortex-m7-gcc-arm-none-eabi`) inherit the `distcc` hidden preset which accelerates cross-compilation by distributing work to a remote build server running the `distcc-bare-metal-builder` Docker image (which provides `arm-none-eabi-gcc` 13.x).
121+
122+
Key environment variables set by the preset:
123+
124+
| Variable | Default | Purpose |
125+
|---|---|---|
126+
| `DISTCC_VERBOSE` | `0` | Set to `1` for verbose distcc output |
127+
| `DISTCC_FALLBACK` | `1` | Fall back to local compilation if the server is unreachable |
128+
| `DISTCC_SKIP_LOCAL_RETRY` | `0` | Retry locally on remote failure |
129+
| `DISTCC_DIR` | `/tmp/distcc` | distcc state directory |
130+
| `PATH` | prepends Arm toolchain | Ensures `arm-none-eabi-gcc` is found |
131+
132+
To use distcc, start the build server container and point `DISTCC_HOSTS` at it:
133+
134+
```bash
135+
# On the build server (or locally in Docker)
136+
docker run --rm -p 3632:3632 ghcr.io/emrainey/distcc-bare-metal-builder:latest
137+
138+
# On your Mac, then run the workflow normally
139+
export DISTCC_HOSTS="localhost/8"
140+
cmake --workflow --preset on-target-cortex-m4-gcc-arm-none-eabi
141+
```
142+
143+
If distcc is not available or the server is unreachable, `DISTCC_FALLBACK=1` ensures the build falls back to local compilation automatically.
144+
145+
The CI presets (`cortex-m4-gcc-arm-none-eabi-ci`, `cortex-m7-gcc-arm-none-eabi-ci`) deliberately omit the `distcc` preset — they build locally inside the CI container where distcc is not available.
146+
147+
### Running CI Jobs Locally with act
148+
149+
If you want to run all CI jobs from `.github/workflows/ci.yml` locally using `act`, create a Python venv and install `PyYAML` (the script uses YAML parsing):
150+
151+
```bash
152+
python3 -m venv venv
153+
source venv/bin/activate
154+
pip install --upgrade pip
155+
pip install pyyaml
156+
# We'll also need jinja2 for builds, but the cmake will install that itself
157+
```
158+
159+
Then `build-all-ci-jobs.py` can run all CI jobs in sequence and report the results. This requires `act` to be installed and configured to run GitHub Actions locally. (Homebrew has `act` available).
160+
161+
```bash
162+
python3 scripts/build-all-ci-jobs.py
163+
```
164+
165+
You can also run all local CMake workflow presets with `build-all-presets.py`.
166+
167+
```bash
168+
python3 scripts/build-all-presets.py
117169
```
118170

119171
## Debug
@@ -125,25 +177,26 @@ $ cmake --workflow --preset unit-tests-clang"
125177
./scripts/debug.sh server
126178

127179
# in another terminal
128-
# modify ./scripts/stm32f407ve.gdb for commands as needed
129180
# and launch the GDB client.
130181
./scripts/debug.sh client
131182
```
132183

133184
### Debug with QEMU
134185

186+
**WARNING**: This is a work in progress and may be disabled or removed at any time as the support for qemu is currently very rough and incomplete. It is only intended to be used as a tool for testing the on-target unit tests in a more "realistic" environment than the native unit tests, but it is not intended to be a full emulation of the hardware or a replacement for Renode or other emulators.
187+
135188
The netduino+2 board can be run on qemu, however, ClockTree, I2C and DMA do not work.
136189

137190
I'm using the arm cross-GDB, CGDB and QEMU from Homebrew.
138191

139192
```bash
140-
qemu-system-arm -M netduinoplus2 -kernel build/cortex-gcc-arm-none-eabi/applications/unittests/ontarget-tests-stm32-qemu-netduinoplus2.bin -s -S
193+
qemu-system-arm -M netduinoplus2 -kernel build/cortex-m4-gcc-arm-none-eabi/applications/unittests/ontarget-tests-stm32-qemu-netduinoplus2.bin -s -S
141194
```
142195

143196
This starts the emulator then waits for the debugger to attach.
144197

145198
```bash
146-
cgdb -d `which arm-none-eabi-gdb` build/cortex-gcc-arm-none-eabi/applications/unittests/ontarget-tests-stm32-qemu-netduinoplus2.elf
199+
cgdb -d `which arm-none-eabi-gdb` build/cortex-m4-gcc-arm-none-eabi/applications/unittests/ontarget-tests-stm32-qemu-netduinoplus2.elf
147200
```
148201

149202
This will start GDB in Curses UI with the arm cross GDB as the backend.

build-support/share/cmake/embedded-superloop/firmware.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ function(add_firmware)
177177

178178
# Generate a debug file for the Ozone debugger for this firmware
179179
get_target_property(LOCAL_BOARD_OZONE ${TARGET_BOARD} OZONE_TEMPLATE)
180-
set(JDEBUG_FILE ${CMAKE_SOURCE_DIR}/${LOCAL_TARGET}.jdebug)
180+
set(JDEBUG_FILE ${CMAKE_SOURCE_DIR}/testing/${LOCAL_TARGET}.jdebug)
181181
configure_file(${LOCAL_BOARD_OZONE} ${JDEBUG_FILE} @ONLY)
182182
get_target_property(LOCAL_BOARD_GDB_CLIENT ${TARGET_BOARD} GDB_CLIENT_TEMPLATE)
183183
set(GDB_FILE ${CMAKE_CURRENT_BINARY_DIR}/${LOCAL_TARGET}.gdb)

embedded-superloop.code-workspace

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@
194194
},
195195
"python.analysis.autoFormatStrings": true,
196196
"python.analysis.typeCheckingMode": "strict",
197-
"python.defaultInterpreterPath": "${command:cmake.buildDirectory}/venv/bin/python3",
197+
"python.defaultInterpreterPath": "${workspaceFolder}/venv/bin/python3",
198198
"testMate.cpp.test.executables": "${workspaceFolder}/build/native-*/modules/**/tests/test-*",
199199
"testMate.cpp.test.parallelExecutionLimit": 2,
200200
"testMate.cpp.test.parallelExecutionOfExecutableLimit": 2,

external/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,15 @@ endif()
7575
# Found on https://discourse.cmake.org/t/possible-to-create-a-python-virtual-env-from-cmake-and-then-find-it-with-findpython3/1132/2
7676
# Find just the interpreter first
7777
find_package(Python3 REQUIRED Interpreter)
78+
set(PYTHON_VENV "${CMAKE_SOURCE_DIR}/venv")
7879
# Print the version and create the virtual environment
7980
execute_process (
8081
COMMAND_ECHO STDOUT
8182
COMMAND ${Python3_EXECUTABLE} --version
82-
COMMAND ${Python3_EXECUTABLE} -m venv ${CMAKE_BINARY_DIR}/venv
83+
COMMAND ${Python3_EXECUTABLE} -m venv ${PYTHON_VENV}
8384
)
8485
# This mimics the activation of the venv
85-
set(ENV{VIRTUAL_ENV} "${CMAKE_BINARY_DIR}/venv")
86+
set(ENV{VIRTUAL_ENV} "${PYTHON_VENV}")
8687
# changes the context of the search
8788
set(Python3_FIND_VIRTUALENV FIRST)
8889
# gets rid of the previous find

include/compiler.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
#else
5555
#define USED
5656
#endif
57-
#if __has_attribute(alias)
57+
// The alias attribute is not supported on Darwin, even though it defines __has_attribute(alias) as true
58+
#if __has_attribute(alias) and not(defined(__APPLE__) or defined(__MACH__))
5859
#define ALIAS(x) ATTRIBUTE((weak, alias(#x)))
5960
#else
6061
#define ALIAS(x) ATTRIBUTE((weak))

modules/jarnax/tests/catch2-monitor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
#include <cinttypes>
44

5+
#include "core/Conversions.hpp"
56
#include "core/Status.hpp"
6-
#include "core/conversions.hpp"
77

88
#include "jarnax/JumpTimer.hpp"
99
#include "jarnax/Monitor.hpp"

0 commit comments

Comments
 (0)