Skip to content

Commit 5c2cd49

Browse files
committed
Add build caching to Build.ps1 for faster execution
Implement timestamp-based caching to avoid rebuilding when no source files have changed. Uses dotnet exec instead of dotnet run for ~11x speedup (from ~10s to ~0.9s on cache hit).
1 parent 35de6e6 commit 5c2cd49

File tree

2 files changed

+142
-4
lines changed

2 files changed

+142
-4
lines changed

Build.ps1

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,78 @@ if (-not $Interactive -or $BuildArgs)
4444

4545
try
4646
{
47+
# Build caching: check if we need to rebuild
48+
$projectPath = Join-Path $PSScriptRoot $EngPath "src" "Build$ProductName.csproj"
4749

48-
# Run the project.
49-
& dotnet run --project (Join-Path $PSScriptRoot $EngPath "src" "Build$ProductName.csproj") -- $BuildArgs
50+
# Find the output DLL by looking for the first DLL in bin/Debug/*/
51+
$binDebugPath = Join-Path $PSScriptRoot $EngPath "src" "bin" "Debug"
52+
$outputDll = $null
53+
if (Test-Path $binDebugPath)
54+
{
55+
$outputDll = Get-ChildItem -Path $binDebugPath -Filter "Build$ProductName.dll" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 | ForEach-Object { $_.FullName }
56+
}
57+
58+
$needsBuild = $false
59+
60+
if (-not $outputDll -or -not (Test-Path $outputDll))
61+
{
62+
# DLL doesn't exist, need to build
63+
$needsBuild = $true
64+
}
65+
else
66+
{
67+
# Get the DLL's last write time
68+
$dllTime = (Get-Item $outputDll).LastWriteTime
69+
70+
# Check files in $EngPath/src (non-recursive)
71+
$engSrcFiles = Get-ChildItem -Path (Join-Path $PSScriptRoot $EngPath "src") -File -ErrorAction SilentlyContinue
72+
73+
# Check files in $EngPath (non-recursive)
74+
$engFiles = Get-ChildItem -Path (Join-Path $PSScriptRoot $EngPath) -File -ErrorAction SilentlyContinue
75+
76+
# Check files in $ScriptRoot (non-recursive)
77+
$rootFiles = Get-ChildItem -Path $PSScriptRoot -File -ErrorAction SilentlyContinue
78+
79+
# Combine all files and check if any are newer than the DLL
80+
$allFiles = @($engSrcFiles) + @($engFiles) + @($rootFiles)
81+
foreach ($file in $allFiles)
82+
{
83+
if ($file.LastWriteTime -gt $dllTime)
84+
{
85+
$needsBuild = $true
86+
break
87+
}
88+
}
89+
}
90+
91+
if ($needsBuild)
92+
{
93+
# Build is needed
94+
Write-Host "Build cache invalid, rebuilding..." -ForegroundColor Cyan
95+
& dotnet build $projectPath
96+
if ($LASTEXITCODE -ne 0)
97+
{
98+
throw "Build failed with exit code $LASTEXITCODE"
99+
}
100+
101+
# Update the DLL timestamp to mark the cache as valid
102+
if ($outputDll -and (Test-Path $outputDll))
103+
{
104+
(Get-Item $outputDll).LastWriteTime = Get-Date
105+
}
106+
}
107+
else
108+
{
109+
Write-Host "Build cache valid, skipping build." -ForegroundColor Green
110+
}
111+
112+
# Run the project using dotnet exec (faster than dotnet run)
113+
if (-not $outputDll -or -not (Test-Path $outputDll))
114+
{
115+
throw "Output DLL not found at: $outputDll"
116+
}
117+
118+
& dotnet exec $outputDll $BuildArgs
50119

51120
if ($StartVsmon)
52121
{

src/PostSharp.Engineering.BuildTools/Resources/Build.ps1

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,78 @@ if (-not $Interactive -or $BuildArgs)
4444

4545
try
4646
{
47+
# Build caching: check if we need to rebuild
48+
$projectPath = Join-Path $PSScriptRoot $EngPath "src" "Build$ProductName.csproj"
4749

48-
# Run the project.
49-
& dotnet run --project (Join-Path $PSScriptRoot $EngPath "src" "Build$ProductName.csproj") -- $BuildArgs
50+
# Find the output DLL by looking for the first DLL in bin/Debug/*/
51+
$binDebugPath = Join-Path $PSScriptRoot $EngPath "src" "bin" "Debug"
52+
$outputDll = $null
53+
if (Test-Path $binDebugPath)
54+
{
55+
$outputDll = Get-ChildItem -Path $binDebugPath -Filter "Build$ProductName.dll" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 | ForEach-Object { $_.FullName }
56+
}
57+
58+
$needsBuild = $false
59+
60+
if (-not $outputDll -or -not (Test-Path $outputDll))
61+
{
62+
# DLL doesn't exist, need to build
63+
$needsBuild = $true
64+
}
65+
else
66+
{
67+
# Get the DLL's last write time
68+
$dllTime = (Get-Item $outputDll).LastWriteTime
69+
70+
# Check files in $EngPath/src (non-recursive)
71+
$engSrcFiles = Get-ChildItem -Path (Join-Path $PSScriptRoot $EngPath "src") -File -ErrorAction SilentlyContinue
72+
73+
# Check files in $EngPath (non-recursive)
74+
$engFiles = Get-ChildItem -Path (Join-Path $PSScriptRoot $EngPath) -File -ErrorAction SilentlyContinue
75+
76+
# Check files in $ScriptRoot (non-recursive)
77+
$rootFiles = Get-ChildItem -Path $PSScriptRoot -File -ErrorAction SilentlyContinue
78+
79+
# Combine all files and check if any are newer than the DLL
80+
$allFiles = @($engSrcFiles) + @($engFiles) + @($rootFiles)
81+
foreach ($file in $allFiles)
82+
{
83+
if ($file.LastWriteTime -gt $dllTime)
84+
{
85+
$needsBuild = $true
86+
break
87+
}
88+
}
89+
}
90+
91+
if ($needsBuild)
92+
{
93+
# Build is needed
94+
Write-Host "Build cache invalid, rebuilding..." -ForegroundColor Cyan
95+
& dotnet build $projectPath
96+
if ($LASTEXITCODE -ne 0)
97+
{
98+
throw "Build failed with exit code $LASTEXITCODE"
99+
}
100+
101+
# Update the DLL timestamp to mark the cache as valid
102+
if ($outputDll -and (Test-Path $outputDll))
103+
{
104+
(Get-Item $outputDll).LastWriteTime = Get-Date
105+
}
106+
}
107+
else
108+
{
109+
Write-Host "Build cache valid, skipping build." -ForegroundColor Green
110+
}
111+
112+
# Run the project using dotnet exec (faster than dotnet run)
113+
if (-not $outputDll -or -not (Test-Path $outputDll))
114+
{
115+
throw "Output DLL not found at: $outputDll"
116+
}
117+
118+
& dotnet exec $outputDll $BuildArgs
50119

51120
if ($StartVsmon)
52121
{

0 commit comments

Comments
 (0)