# 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=<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.
