mirror of https://github.com/stascorp/rdpwrap
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
10 KiB
260 lines
10 KiB
#!/usr/bin/env pwsh
|
|
# tools/build-local.ps1
|
|
# Full local build: C++ DLLs + C# tools → ./build/
|
|
#
|
|
# Usage (run from repo root):
|
|
# .\tools\build-local.ps1 # full build
|
|
# .\tools\build-local.ps1 -SkipCpp # skip C++ DLL (faster for C# iteration)
|
|
# .\tools\build-local.ps1 -SkipMsi # skip MSI build (no WiX needed)
|
|
#
|
|
# See docs/BUILDING.md for prerequisites and troubleshooting.
|
|
|
|
#Requires -Version 5
|
|
|
|
param(
|
|
[switch]$SkipCpp,
|
|
[switch]$SkipIcons,
|
|
[switch]$SkipMsi
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$REPO = $PSScriptRoot | Split-Path -Parent
|
|
$BUILD = Join-Path $REPO "build"
|
|
|
|
# ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
|
|
function Step([string]$msg) {
|
|
Write-Host "`n==> $msg" -ForegroundColor Cyan
|
|
}
|
|
|
|
function Fail([string]$msg) {
|
|
Write-Host "[FAIL] $msg" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# ─── Locate MSBuild ───────────────────────────────────────────────────────────
|
|
|
|
function Find-MSBuild {
|
|
$candidates = @(
|
|
# VS 2022 Build Tools / Community
|
|
"${env:ProgramFiles}\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
|
"${env:ProgramFiles}\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
|
"${env:ProgramFiles}\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
|
# VS 2019 Build Tools / Community
|
|
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
|
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\amd64\MSBuild.exe",
|
|
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\MSBuild.exe"
|
|
)
|
|
foreach ($p in $candidates) {
|
|
if (Test-Path $p) { return $p }
|
|
}
|
|
# Fall back to PATH
|
|
$found = Get-Command msbuild -ErrorAction SilentlyContinue
|
|
if ($found) { return $found.Source }
|
|
return $null
|
|
}
|
|
|
|
# ─── 0. Stamp INI date ────────────────────────────────────────────────────────
|
|
|
|
Step "Stamping rdpwrap.ini with today's date"
|
|
$today = Get-Date -Format "yyyy-MM-dd"
|
|
$iniFile = "$REPO\msi\rdpwrap.ini"
|
|
(Get-Content $iniFile) -replace '^Updated=.*', "Updated=$today" | Set-Content $iniFile
|
|
Write-Host " Updated= $today"
|
|
|
|
# Stage INI into RDPWInst embedded resources so it gets compiled in
|
|
$iniDest = "$REPO\src-csharp\RDPWInst\Resources\rdpwrap.ini"
|
|
New-Item -Force -ItemType Directory (Split-Path $iniDest) | Out-Null
|
|
Copy-Item $iniFile $iniDest -Force
|
|
Write-Host " Staged: src-csharp/RDPWInst/Resources/rdpwrap.ini"
|
|
|
|
# ─── 1. Icons ─────────────────────────────────────────────────────────────────
|
|
|
|
if (-not $SkipIcons) {
|
|
Step "Generating application icons"
|
|
& "$REPO\tools\make-icons.ps1"
|
|
}
|
|
|
|
# ─── 2. C++ DLLs ──────────────────────────────────────────────────────────────
|
|
|
|
if (-not $SkipCpp) {
|
|
Step "Building C++ DLLs (x64 + Win32)"
|
|
|
|
$msbuild = Find-MSBuild
|
|
if (-not $msbuild) {
|
|
Fail "MSBuild not found. Install Visual Studio 2019 or 2022 Build Tools with 'Desktop development with C++'."
|
|
}
|
|
Write-Host " Using MSBuild: $msbuild"
|
|
|
|
$msbuildArgs = @(
|
|
"$REPO\src-x86-x64-Fusix\RDPWrap.sln",
|
|
"/p:Configuration=Release",
|
|
"/p:PlatformToolset=v143",
|
|
"/p:WindowsTargetPlatformVersion=10.0",
|
|
"/m", "/v:m"
|
|
)
|
|
|
|
foreach ($platform in @("x64", "Win32", "ARM64")) {
|
|
Write-Host " Building $platform..."
|
|
& $msbuild @msbuildArgs "/p:Platform=$platform"
|
|
if ($LASTEXITCODE -ne 0) { Fail "MSBuild failed for $platform" }
|
|
}
|
|
} else {
|
|
Write-Host "[skip] C++ DLL build (-SkipCpp)" -ForegroundColor Yellow
|
|
}
|
|
|
|
# ─── 3. C# tools ──────────────────────────────────────────────────────────────
|
|
|
|
Step "Publishing C# tools"
|
|
|
|
# Verify dotnet
|
|
$dotnetVer = (dotnet --version 2>&1)
|
|
Write-Host " .NET SDK: $dotnetVer"
|
|
|
|
$tools = @("RDPConf", "RDPCheck", "RDPWInst")
|
|
$rids = @("win-x64", "win-x86", "win-arm64")
|
|
|
|
foreach ($tool in $tools) {
|
|
foreach ($rid in $rids) {
|
|
$arch = $rid -replace "win-", ""
|
|
$staging = Join-Path $BUILD "staging\$tool\$rid"
|
|
Write-Host " $tool / $rid → $staging"
|
|
|
|
dotnet publish "$REPO\src-csharp\$tool\$tool.csproj" `
|
|
-c Release -r $rid `
|
|
--self-contained true `
|
|
-p:PublishSingleFile=true `
|
|
-p:IncludeNativeLibrariesForSelfExtract=true `
|
|
-p:PublishTrimmed=false `
|
|
-p:Version=1.0.0 `
|
|
-o $staging `
|
|
--nologo -v quiet
|
|
|
|
if ($LASTEXITCODE -ne 0) { Fail "dotnet publish failed for $tool/$rid" }
|
|
}
|
|
}
|
|
|
|
# ─── 4. Assemble build/ ───────────────────────────────────────────────────────
|
|
|
|
Step "Assembling ./build/"
|
|
|
|
New-Item -Force -ItemType Directory $BUILD | Out-Null
|
|
|
|
# C++ DLLs
|
|
if (-not $SkipCpp) {
|
|
$dllMap = @{
|
|
"rdpwrap_x64.dll" = "$REPO\src-x86-x64-Fusix\Release\x64\RDPWrap.dll"
|
|
"rdpwrap_x86.dll" = "$REPO\src-x86-x64-Fusix\Release\x86\RDPWrap.dll"
|
|
"rdpwrap_arm64.dll" = "$REPO\src-x86-x64-Fusix\Release\arm64\RDPWrap.dll"
|
|
}
|
|
foreach ($dest in $dllMap.Keys) {
|
|
$src = $dllMap[$dest]
|
|
if (Test-Path $src) {
|
|
Copy-Item $src "$BUILD\$dest" -Force
|
|
Write-Host " Copied: $dest"
|
|
} else {
|
|
Write-Warning " Not found (DLL build skipped?): $src"
|
|
}
|
|
}
|
|
}
|
|
|
|
# C# executables
|
|
foreach ($tool in $tools) {
|
|
foreach ($rid in $rids) {
|
|
$arch = $rid -replace "win-", ""
|
|
$src = "$BUILD\staging\$tool\$rid\$tool.exe"
|
|
$dest = "$BUILD\${tool}_${arch}.exe"
|
|
if (Test-Path $src) {
|
|
Copy-Item $src $dest -Force
|
|
Write-Host " Copied: ${tool}_${arch}.exe"
|
|
} else {
|
|
Write-Warning " Not found: $src"
|
|
}
|
|
}
|
|
}
|
|
|
|
# INI file (side-by-side with installer, and for reference)
|
|
Copy-Item $iniFile "$BUILD\rdpwrap.ini" -Force
|
|
Write-Host " Copied: rdpwrap.ini"
|
|
|
|
# Remove staging area
|
|
Remove-Item -Recurse -Force "$BUILD\staging" -ErrorAction SilentlyContinue
|
|
|
|
# ─── 5. MSI ───────────────────────────────────────────────────────────────────
|
|
|
|
if (-not $SkipMsi) {
|
|
Step "Building MSI (WiX v5)"
|
|
|
|
$wixProj = "$REPO\msi\RDPWInst.wixproj"
|
|
$pkgVer = Get-Date -Format "yy.M.d" # MSI version: major<=255, e.g. 26.4.1
|
|
|
|
foreach ($arch in @('x64', 'x86', 'arm64')) {
|
|
# Verify this arch's inputs exist in build/
|
|
$required = @(
|
|
"$BUILD\RDPWInst_$arch.exe",
|
|
"$BUILD\RDPConf_$arch.exe",
|
|
"$BUILD\RDPCheck_$arch.exe",
|
|
"$BUILD\rdpwrap_$arch.dll",
|
|
"$BUILD\rdpwrap.ini"
|
|
)
|
|
$missing = $required | Where-Object { -not (Test-Path $_) }
|
|
if ($missing) {
|
|
Write-Warning " Skipping $arch MSI -- missing inputs:`n $($missing -join "`n ")"
|
|
continue
|
|
}
|
|
|
|
# Stage inputs next to the .wixproj (WiX resolves Source= relative to the project)
|
|
foreach ($inputFile in $required) {
|
|
Copy-Item $inputFile "$REPO\msi\" -Force -ErrorAction Continue
|
|
}
|
|
|
|
# Explicit OutputPath per-arch avoids WiX placing all builds in the same bin/x86 dir.
|
|
# Explicit OutputName overrides the $(Platform) token which WiX doesn't expand in OutputName.
|
|
$outDir = Join-Path $REPO "msi_out\$arch"
|
|
$wixOut = Join-Path $outDir "RDPWrapper-$arch.msi"
|
|
New-Item -Force -ItemType Directory $outDir | Out-Null
|
|
|
|
# Use Continue so a non-zero exit from dotnet/WiX does NOT throw under ErrorActionPreference=Stop
|
|
$buildArgs = @('build', $wixProj, '-c', 'Release',
|
|
"/p:Platform=$arch",
|
|
"/p:OutputName=RDPWrapper-$arch",
|
|
"/p:OutputPath=$outDir",
|
|
"/p:PackageVersion=$pkgVer",
|
|
'--nologo')
|
|
& dotnet @buildArgs
|
|
$wixExit = $LASTEXITCODE
|
|
if ($wixExit -ne 0) {
|
|
Write-Warning " MSI build failed for $arch (exit $wixExit) -- continuing."
|
|
continue
|
|
}
|
|
|
|
$msiSrc = if (Test-Path $wixOut) {
|
|
Get-Item $wixOut
|
|
} else {
|
|
# Fallback: WiX may insert a locale subdir (e.g. msi_out/x64/en-US/…)
|
|
Get-ChildItem $outDir -Recurse -Filter "RDPWrapper-$arch.msi" -ErrorAction SilentlyContinue |
|
|
Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
}
|
|
if ($msiSrc) {
|
|
$dest = Join-Path $BUILD "RDPWrapper-$pkgVer-$arch.msi"
|
|
Copy-Item $msiSrc.FullName $dest -Force
|
|
Write-Host (" Produced: RDPWrapper-$pkgVer-$arch.msi ({0:N1} MB)" -f ($msiSrc.Length / 1MB))
|
|
} else {
|
|
Write-Warning " MSI output not found after $arch build."
|
|
}
|
|
}
|
|
} else {
|
|
Write-Host "[skip] MSI build (-SkipMsi)" -ForegroundColor Yellow
|
|
}
|
|
|
|
# ─── 6. Summary ───────────────────────────────────────────────────────────────
|
|
|
|
Step "Build complete"
|
|
Get-ChildItem $BUILD | Sort-Object Name | ForEach-Object {
|
|
$kb = [math]::Round($_.Length / 1KB, 0)
|
|
Write-Host (" {0,-28} {1,6} KB" -f $_.Name, $kb)
|
|
}
|
|
Write-Host ""
|