# Agent Guide - Building and Compiling This document provides the correct procedures for building this RP2350 project. Follow these instructions to avoid common pitfalls. ## Build System This project uses: - **CMake** for configuration - **Ninja** as the build system (not Make) - **Pico SDK 2.2.0** with the VS Code extension ## Initial Setup The project must be configured with CMake using the **Ninja generator** before building: ```bash cd /Users/adolforeyna/Projects/pico-bare-metal/Adolfo/basic1 rm -rf build # Clean start cmake -B build -G Ninja -DPICO_BOARD=adafruit_feather_rp2350 ``` **IMPORTANT:** Always specify `-G Ninja` when running cmake. Without it, CMake generates Makefiles which won't work with the ninja command. ## Building ### Using Ninja Directly After cmake configuration: ```bash cd /Users/adolforeyna/Projects/pico-bare-metal/Adolfo/basic1/build ninja ``` Or from project root: ```bash cd /Users/adolforeyna/Projects/pico-bare-metal/Adolfo/basic1 ninja -C build ``` ### Using VS Code Task The project has a "Compile Project" task that runs: ```bash /Users/adolforeyna/.pico-sdk/ninja/v1.12.1/ninja -C /path/to/build ``` However, this task will fail if `build.ninja` doesn't exist. You must run cmake first. ### Quick Rebuild If you only changed source files (not CMakeLists.txt): ```bash cd build ninja ``` If you changed CMakeLists.txt or added/removed files: ```bash cd build cmake -G Ninja .. ninja ``` ## Building for Different Boards ### Single Board ```bash # Clean and configure for specific board rm -rf build cmake -B build -G Ninja -DPICO_BOARD=pico2 cd build && ninja ``` Available boards: - `adafruit_feather_rp2350` (default) - `pico2` - `pico2_w` ### All Boards at Once Use the provided script: ```bash ./build_all_boards.sh ``` This creates: - `build_adafruit_feather_rp2350/basic1.uf2` → `basic1_adafruit_feather_rp2350.uf2` - `build_pico2/basic1.uf2` → `basic1_pico2.uf2` - `build_pico2_w/basic1.uf2` → `basic1_pico2_w.uf2` ## Verifying Build Success ### Check for Output Files ```bash ls -lh build/basic1.{uf2,elf,bin} ``` Successful build produces: - `basic1.uf2` - Flash file for bootloader (≈150KB) - `basic1.elf` - Executable with debug symbols (≈1.1MB) - `basic1.bin` - Raw binary (≈74KB) - `basic1.hex` - Intel HEX format - `basic1.dis` - Disassembly (≈877KB) ### Check File Timestamp ```bash stat build/basic1.uf2 ``` Verify the modification time is recent. ### Look for Ninja Success Message Successful build ends with: ``` [90/90] Linking CXX executable basic1.elf ``` Failed build shows: ``` ninja: build stopped: subcommand failed. ``` ## Common Issues and Solutions ### Issue: "ninja: error: loading 'build.ninja': No such file or directory" **Cause:** CMake wasn't run or didn't generate Ninja files **Solution:** ```bash cd /Users/adolforeyna/Projects/pico-bare-metal/Adolfo/basic1 cmake -B build -G Ninja -DPICO_BOARD=adafruit_feather_rp2350 ``` ### Issue: Build directory has Makefiles instead of build.ninja **Cause:** CMake was run without `-G Ninja` **Solution:** ```bash rm -rf build cmake -B build -G Ninja -DPICO_BOARD=adafruit_feather_rp2350 ``` ### Issue: Compilation errors after adding new files **Cause:** CMakeLists.txt not updated or cmake not re-run **Solution:** 1. Add new files to `CMakeLists.txt` in the `add_executable()` section 2. Re-run cmake: ```bash cd build cmake -G Ninja .. ninja ``` ### Issue: Changes not reflected in build **Cause:** Stale build cache **Solution:** ```bash cd build ninja clean ninja ``` Or full rebuild: ```bash rm -rf build cmake -B build -G Ninja -DPICO_BOARD=adafruit_feather_rp2350 cd build && ninja ``` ## Checking for Errors ### Compilation Errors Look for errors in ninja output: ``` [12/90] Building CXX object CMakeFiles/basic1.dir/basic1.cpp.o FAILED: CMakeFiles/basic1.dir/basic1.cpp.o ... error: 'foo' was not declared in this scope ``` ### Viewing Recent Build Output ```bash cd build ninja 2>&1 | tail -50 # Last 50 lines ``` ### Viewing Full Build Output ```bash cd build ninja 2>&1 | tee build.log ``` ## Build Output Location ``` build/ ├── basic1.uf2 # Main flash file ├── basic1.elf # Executable with symbols ├── basic1.bin # Raw binary ├── basic1.hex # Intel HEX ├── basic1.dis # Disassembly ├── basic1.elf.map # Memory map ├── build.ninja # Ninja build file (must exist!) ├── CMakeCache.txt # CMake configuration └── compile_commands.json # For IDE integration ``` ## Integration with Tools ### VS Code Tasks The project includes pre-configured tasks in `.vscode/tasks.json`: - **Compile Project** - Runs ninja in build directory These tasks expect `build/build.ninja` to exist. ### CMake Extension If using CMake Tools extension: 1. Select kit: "Pico ARM GCC" 2. Configure with Ninja generator 3. Build target: "basic1" ## Quick Reference Commands ```bash # Full clean build (default board) rm -rf build && cmake -B build -G Ninja && ninja -C build # Full clean build (specific board) rm -rf build && cmake -B build -G Ninja -DPICO_BOARD=pico2 && ninja -C build # Incremental build ninja -C build # Build all boards ./build_all_boards.sh # Check build output ls -lh build/basic1.uf2 # View compile commands cat build/compile_commands.json | grep -A5 basic1.cpp ``` ## Testing Build Success After building, you can verify the binary contains expected symbols: ```bash arm-none-eabi-nm build/basic1.elf | grep -i main arm-none-eabi-size build/basic1.elf ``` ## Important Notes 1. **Always use `-G Ninja`** when running cmake 2. **The build directory must be recreated** when switching boards 3. **ninja must be run from the build directory** or with `-C build` 4. **CMake must be re-run** after modifying CMakeLists.txt 5. **The Pico SDK path** is at `~/.pico-sdk/sdk/2.2.0` 6. **The toolchain** is at `~/.pico-sdk/toolchain/14_2_Rel1` 7. **Output files** are always in the `build/` directory (or board-specific build dirs) ## When Making Changes | Change Type | Required Action | |-------------|-----------------| | Source code (.cpp, .c) | `ninja -C build` | | Header files (.h) | `ninja -C build` | | CMakeLists.txt | `cd build && cmake -G Ninja .. && ninja` | | New board | `rm -rf build && cmake -B build -G Ninja -DPICO_BOARD= && ninja -C build` | | New files | Update CMakeLists.txt, then re-run cmake | | board_config.h | `ninja -C build` | ## Flashing After successful build: 1. **Manual:** Hold BOOTSEL, connect USB, copy `build/basic1.uf2` to mounted drive 2. **Script:** `./build_and_flash.sh` (requires openocd or picotool) 3. **VS Code:** Use "Run Project" or "Flash" tasks ## Serial Monitor View serial output: ```bash screen /dev/cu.usbmodem101 # Exit: Ctrl-A, then K, then Y ``` Or use VS Code's serial monitor extension.