# build.ps1 -- Compile the sketch using arduino-cli # # Reads all settings from .anvil.toml. No Anvil binary required. # Called by build.bat (thin wrapper) or directly: # powershell -File build.ps1 [--board NAME] [--clean] [--verbose] # # Exit codes: 0 = success, 1 = error param( [string]$board = "", [switch]$clean, [switch]$verbose, [switch]$help ) $ErrorActionPreference = "Stop" # -- Helpers --------------------------------------------------------------- function Fail($msg) { Write-Host "FAIL: $msg" -ForegroundColor Red exit 1 } function Ok($msg) { Write-Host "ok $msg" -ForegroundColor Green } # -- Locate config --------------------------------------------------------- $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition $Config = Join-Path $ScriptDir ".anvil.toml" if (-not (Test-Path $Config)) { Fail "No .anvil.toml found in $ScriptDir" } # -- Parse .anvil.toml ----------------------------------------------------- # Simple line-by-line parser. Tracks current section header to support # [project], [build], [boards.NAME], etc. $tomlData = @{} $currentSection = "" foreach ($rawLine in Get-Content $Config) { $line = $rawLine.Trim() # Skip blank lines and comments if ($line -eq "" -or $line.StartsWith("#")) { continue } # Section header: [project], [boards.uno], etc. if ($line -match '^\[(.+)\]$') { $currentSection = $Matches[1] continue } # Key = value (only process lines with =) if ($line -match '^([^=]+?)\s*=\s*(.+)$') { $key = $Matches[1].Trim() $val = $Matches[2].Trim() # Strip surrounding quotes if ($val.StartsWith('"') -and $val.EndsWith('"')) { $val = $val.Substring(1, $val.Length - 2) } # Skip array values (multi-line or inline [...]) if ($val.StartsWith("[")) { continue } $fullKey = if ($currentSection) { "$currentSection.$key" } else { $key } $tomlData[$fullKey] = $val } } # -- Extract settings ------------------------------------------------------ $SketchName = $tomlData["project.name"] $DefaultBoard = $tomlData["build.default"] $Warnings = $tomlData["build.warnings"] if (-not $SketchName) { Fail "Could not read project name from .anvil.toml" } $SketchDir = Join-Path $ScriptDir $SketchName $BuildDir = Join-Path $ScriptDir ".build" # -- Help ------------------------------------------------------------------ if ($help) { Write-Host "Usage: build.bat [--board NAME] [--clean] [--verbose]" Write-Host " Compiles the sketch. Settings from .anvil.toml." Write-Host " --board NAME selects a board from [boards.NAME]." exit 0 } # -- Resolve board --------------------------------------------------------- $BoardName = if ($board) { $board } else { $DefaultBoard } if (-not $BoardName) { Fail @" No default board set in .anvil.toml. Add a default to the [build] section of .anvil.toml: default = "uno" And make sure a matching [boards.uno] section exists: [boards.uno] fqbn = "arduino:avr:uno" Or with Anvil: Anvil board --default uno List boards: Anvil board --listall arduino-cli board listall "@ } $Fqbn = $tomlData["boards.$BoardName.fqbn"] if (-not $Fqbn) { Fail @" No [boards.$BoardName] section in .anvil.toml. Add it to .anvil.toml: [boards.$BoardName] fqbn = "arduino:avr:uno" (replace with your board) Or with Anvil: Anvil board --add $BoardName List boards: Anvil board --listall arduino-cli board listall "@ } if ($BoardName -ne $DefaultBoard) { Ok "Using board: $BoardName -- $Fqbn" } # -- Preflight ------------------------------------------------------------- $arduinoCli = Get-Command "arduino-cli" -ErrorAction SilentlyContinue if (-not $arduinoCli) { Fail "arduino-cli not found in PATH." } if (-not (Test-Path $SketchDir)) { Fail "Sketch directory not found: $SketchDir" } # -- Clean ----------------------------------------------------------------- if ($clean -and (Test-Path $BuildDir)) { Write-Host "Cleaning build cache..." Remove-Item -Recurse -Force $BuildDir } # -- Build include flags --------------------------------------------------- $buildFlags = @() foreach ($sub in @("lib\hal", "lib\app")) { $dir = Join-Path $ScriptDir $sub if (Test-Path $dir) { $buildFlags += "-I$dir" } } # Auto-discover driver libraries (added by: anvil add ) $driversDir = Join-Path $ScriptDir "lib\drivers" if (Test-Path $driversDir) { foreach ($d in Get-ChildItem -Path $driversDir -Directory) { $buildFlags += "-I$($d.FullName)" } } $buildFlags += "-Werror" $flagsStr = $buildFlags -join " " # -- Compile --------------------------------------------------------------- Write-Host "Compiling $SketchName..." Write-Host " Board: $Fqbn" Write-Host " Sketch: $SketchDir" Write-Host "" if (-not (Test-Path $BuildDir)) { New-Item -ItemType Directory -Path $BuildDir | Out-Null } $compileArgs = @( "compile" "--fqbn", $Fqbn "--build-path", $BuildDir "--warnings", $Warnings "--build-property", "compiler.cpp.extra_flags=$flagsStr" "--build-property", "compiler.c.extra_flags=$flagsStr" ) if ($verbose) { $compileArgs += "--verbose" } $compileArgs += $SketchDir & arduino-cli @compileArgs if ($LASTEXITCODE -ne 0) { Write-Host "" Fail "Compilation failed." } Write-Host "" Ok "Compile succeeded." Write-Host "" exit 0