<# .SYNOPSIS SHT30 온습도 STM32F407 펌웨어 빌드 (sht30_fw) — Ninja + arm-none-eabi. .DESCRIPTION firmware/ 를 소스 루트로, firmware/build 를 빌드 디렉터리로 CMake(Ninja) 구성/빌드한다. 크로스 툴체인 파일(cmake/arm-none-eabi-toolchain.cmake)을 사용하며, sht30_fw 실행 타깃을 산출한다. 폐쇄망(air-gapped): 이 스크립트는 네트워크에 접속하지 않는다. 모든 의존성은 firmware/third_party 에 사전 벤더링되어 있어야 한다(scripts/vendor.ps1 참조). third_party 가 없으면 CMake configure 단계에서 즉시 실패한다. .PARAMETER BuildType CMAKE_BUILD_TYPE (Release | RelWithDebInfo | Debug). 기본 Release. .PARAMETER Clean 빌드 디렉터리를 먼저 삭제하고 새로 구성한다(클린 빌드). .PARAMETER ToolchainPrefix arm-none-eabi 접두 경로 override (PATH 에 없을 때). 예) "C:/Program Files (x86)/Arm/GNU Toolchain mingw-w64-i686-arm-none-eabi/bin/arm-none-eabi-" .EXAMPLE pwsh firmware/scripts/build.ps1 pwsh firmware/scripts/build.ps1 -Clean -BuildType RelWithDebInfo #> [CmdletBinding()] param( [ValidateSet('Release', 'RelWithDebInfo', 'Debug')] [string]$BuildType = 'Release', [switch]$Clean, [string]$ToolchainPrefix, # 자리표시자(PLACEHOLDER) 서버 CA 상태로도 빌드를 강행한다(테스트 전용). [switch]$AllowPlaceholderCA ) $ErrorActionPreference = 'Stop' # 빌드 타깃은 SHT30 단일 보드(sht30_fw). $Target = 'sht30_fw' # ── 경로 산출 (스크립트 위치 기준, cwd 무관) ───────────────────────────────── $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $FwRoot = Split-Path -Parent $ScriptDir # .../firmware $BuildDir = Join-Path $FwRoot 'build' $Toolchain = Join-Path $FwRoot 'cmake/arm-none-eabi-toolchain.cmake' Write-Host "==== SHT30 STM32F407 펌웨어 빌드 ====" -ForegroundColor Cyan Write-Host " firmware root : $FwRoot" Write-Host " build dir : $BuildDir" Write-Host " build type : $BuildType" Write-Host " target : $Target" # ── 사전 점검: 필수 도구 ───────────────────────────────────────────────────── function Assert-Tool([string]$name) { if (-not (Get-Command $name -ErrorAction SilentlyContinue)) { throw "필수 도구를 찾을 수 없습니다: $name (PATH 확인)" } } Assert-Tool 'cmake' Assert-Tool 'ninja' # 툴체인 컴파일러 존재 확인(접두 override 미지정 시 PATH 에서 arm-none-eabi-gcc). if (-not $ToolchainPrefix) { if (-not (Get-Command 'arm-none-eabi-gcc' -ErrorAction SilentlyContinue)) { throw "arm-none-eabi-gcc 를 PATH 에서 찾을 수 없습니다. -ToolchainPrefix 로 지정하세요." } } # ── 폐쇄망 가드: third_party 벤더링 확인 ───────────────────────────────────── $ThirdParty = Join-Path $FwRoot 'third_party' if (-not (Test-Path $ThirdParty)) { throw @" third_party 가 없습니다(폐쇄망 빌드 전 벤더링 필요). networked 빌드 머신에서 먼저 실행하세요: pwsh firmware/scripts/vendor.ps1 "@ } # ── 배포 가드: 자리표시자(PLACEHOLDER) 서버 CA 검출 ────────────────────────── # server_ca.c 가 자리표시자면 부팅 시 tls_init() 의 X.509 파싱이 실패해 bsp_fatal() # 로 안전 정지한다(데이터 유출은 없으나 동작 불가). "조용한 부팅 실패"를 피하려고 # 빌드 단계에서 미리 차단한다. 실제 Cafe24 루트 CA 로 교체해야 한다(certs/README.md). $ServerCa = Join-Path $FwRoot 'certs/server_ca.c' if ((Test-Path $ServerCa) -and (Select-String -Path $ServerCa -SimpleMatch 'PLACEHOLDER' -Quiet)) { if ($AllowPlaceholderCA) { Write-Warning "server_ca.c 가 자리표시자(PLACEHOLDER) 입니다 — 이 펌웨어는 부팅 시 TLS 초기화 실패로 정지합니다(-AllowPlaceholderCA 로 강행)." } else { throw @" server_ca.c 가 자리표시자(PLACEHOLDER) 상태입니다 — 실제 Cafe24 루트 CA 로 교체해야 합니다. 이 상태로 빌드한 펌웨어는 부팅 시 tls_init() 이 bsp_fatal() 로 정지합니다(동작 불가). 교체: firmware/certs/README.md 및 certs/gen_ca_header.ps1 참고. (테스트 목적 강행: build.ps1 ... -AllowPlaceholderCA) "@ } } # ── 클린 빌드 ──────────────────────────────────────────────────────────────── if ($Clean -and (Test-Path $BuildDir)) { Write-Host " (clean) 기존 빌드 디렉터리 삭제: $BuildDir" -ForegroundColor Yellow Remove-Item -Recurse -Force $BuildDir } # ── Configure (Ninja + 툴체인) ─────────────────────────────────────────────── $cfgArgs = @( '-S', $FwRoot '-B', $BuildDir '-G', 'Ninja' "-DCMAKE_TOOLCHAIN_FILE=$Toolchain" "-DCMAKE_BUILD_TYPE=$BuildType" ) if ($ToolchainPrefix) { $cfgArgs += "-DTOOLCHAIN_PREFIX=$ToolchainPrefix" } Write-Host "`n[1/2] cmake configure …" -ForegroundColor Green & cmake @cfgArgs if ($LASTEXITCODE -ne 0) { throw "cmake configure 실패 (exit $LASTEXITCODE)" } # ── Build ──────────────────────────────────────────────────────────────────── $buildArgs = @('--build', $BuildDir, '--target', $Target) Write-Host "`n[2/2] cmake build ($Target) …" -ForegroundColor Green & cmake @buildArgs if ($LASTEXITCODE -ne 0) { throw "빌드 실패 (exit $LASTEXITCODE)" } # ── 산출물 요약 ────────────────────────────────────────────────────────────── Write-Host "`n==== 빌드 완료. 산출물 ====" -ForegroundColor Cyan Get-ChildItem -Path $BuildDir -Recurse -Include '*.elf', '*.bin', '*.hex', '*.map' ` -ErrorAction SilentlyContinue | ForEach-Object { '{0,12:N0} {1}' -f $_.Length, $_.FullName } | Write-Host