#Requires -Version 5.1 <# .SYNOPSIS Build Orisys Customer Windows onedir EXE with PyInstaller. .PARAMETER Clean Pass --clean to PyInstaller (slower; use when deps/spec change). .PARAMETER SkipInstall Skip pip install steps (reuse existing .venv-build packages). #> param( [switch]$Clean, [switch]$SkipInstall ) $ErrorActionPreference = "Stop" $RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path $VenvDir = Join-Path $RepoRoot ".venv-build" $Python = Join-Path $VenvDir "Scripts\python.exe" $Spec = Join-Path $PSScriptRoot "orisys-customer.spec" $WorkPath = Join-Path $RepoRoot "build\_pyinstaller" $DistPath = Join-Path $RepoRoot "dist" Write-Host "Repo: $RepoRoot" if (-not (Test-Path $Python)) { Write-Host "Creating build venv at $VenvDir" python -m venv $VenvDir } if (-not $SkipInstall) { Write-Host "Installing build dependencies (editable shared + customer + orisys + pyinstaller)…" & $Python -m pip install --upgrade pip & $Python -m pip install "pyinstaller>=6.0" & $Python -m pip install -e (Join-Path $RepoRoot "shared") & $Python -m pip install -e (Join-Path $RepoRoot "apps\customer") # orisys may already be installed; ensure present without [gui]/open3d & $Python -m pip install "orisys>=0.5" Write-Host "Forcing opencv-python-headless 4.x (orisys may have pulled opencv-python; 5.x can be broken)…" & $Python -m pip uninstall -y opencv-python opencv-python-headless 2>$null & $Python -m pip install "opencv-python-headless>=4.10.0.84,<5" & $Python -c "import cv2; print('cv2 OK', cv2.__version__)" if ($LASTEXITCODE -ne 0) { Write-Error "cv2 import failed after installing opencv-python-headless" exit $LASTEXITCODE } # Guard: Open3D must not be present in the build env $hasOpen3d = & $Python -c "import importlib.util; print(importlib.util.find_spec('open3d') is not None)" if ($hasOpen3d -eq "True") { Write-Host "Uninstalling open3d from build venv…" & $Python -m pip uninstall -y open3d } } $pyiArgs = @( "--noconfirm", "--distpath", $DistPath, "--workpath", $WorkPath, $Spec ) if ($Clean) { $pyiArgs = @("--clean") + $pyiArgs } Write-Host "Running PyInstaller…" & $Python -m PyInstaller @pyiArgs if ($LASTEXITCODE -ne 0) { Write-Error "PyInstaller failed with exit code $LASTEXITCODE" exit $LASTEXITCODE } $OutDir = Join-Path $DistPath "OrisysCustomer" Write-Host "" Write-Host "Build complete: $OutDir" # Lean config beside EXE (exclude finger visualization assets) $ConfigSrc = Join-Path $RepoRoot "apps\customer\config" $ConfigDst = Join-Path $OutDir "config" if (Test-Path $ConfigSrc) { Write-Host "Copying lean config to $ConfigDst …" if (Test-Path $ConfigDst) { Remove-Item $ConfigDst -Recurse -Force } New-Item -ItemType Directory -Path $ConfigDst -Force | Out-Null Get-ChildItem $ConfigSrc -Force | ForEach-Object { Copy-Item $_.FullName -Destination $ConfigDst -Recurse -Force } $viz = Join-Path $ConfigDst "sensors\finger\assets\visualization" if (Test-Path $viz) { Remove-Item $viz -Recurse -Force Write-Host "Excluded sensors/finger/assets/visualization" } } Write-Host "Launch: $(Join-Path $OutDir 'OrisysCustomer.exe')" # Size summary if (Test-Path $OutDir) { $bytes = (Get-ChildItem $OutDir -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum $mb = [math]::Round($bytes / 1MB, 1) Write-Host ("Output size: {0} MB" -f $mb) $o3dHits = Get-ChildItem $OutDir -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Name -match 'open3d' } if ($o3dHits) { Write-Warning "Open3D-related files found under dist (should be empty):" $o3dHits | ForEach-Object { Write-Warning $_.FullName } } else { Write-Host "Open3D check: none found under dist." } }