Skip to content

Commit f4fd0c4

Browse files
committed
ci: install C++ build tools for Windows AOT
The Windows release jobs publish the executable with Native AOT, which links the final binary with the MSVC linker (link.exe). The 1ES hosted images do not ship the C++ toolchain, so every Windows leg fails with "Platform linker not found" from Microsoft.NETCore.Native.Windows.targets. Add a setup script that installs VS 2022 Build Tools with the single VC.Tools component for the agent's architecture - x86.x64 on the Intel legs (win-x86, win-x64), ARM64 on the Arm leg (win-arm64) - and run it before the publish step. Installing just the architecture's component keeps the download to the minimum that still provides link.exe and the MSVC libraries; the .NET ILCompiler then discovers the toolchain through the Visual Studio setup API. Assisted-by: Claude Opus 4.8 Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
1 parent ff75035 commit f4fd0c4

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

.azure-pipelines/release.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ extends:
139139
inputs:
140140
packageType: sdk
141141
version: '10.x'
142+
# Native AOT links the published binary with the MSVC linker,
143+
# which the hosted images do not ship by default. Install the
144+
# VC++ build tools for the agent's architecture first.
145+
- task: PowerShell@2
146+
displayName: 'Install C++ build tools for AOT'
147+
inputs:
148+
filePath: '.azure-pipelines/scripts/windows/setup-aot-build-tools.ps1'
149+
arguments: -Architecture ${{ dim.poolArch }}
142150
# Publish the application payload.
143151
- task: PowerShell@2
144152
displayName: 'Publish payload'
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Install the MSVC C++ build tools that Native AOT needs to link the
2+
# git-credential-manager binary on Windows agents.
3+
#
4+
# Publishing with PublishAot=true invokes the platform linker (link.exe)
5+
# from the MSVC toolchain. The 1ES hosted images do not ship it by
6+
# default, so the AOT publish fails with "Platform linker not found"
7+
# (Microsoft.NETCore.Native.Windows.targets). See
8+
# https://aka.ms/nativeaot-prerequisites.
9+
#
10+
# Install VS 2022 Build Tools with the single VC.Tools component for the
11+
# agent's architecture - the smallest selection that provides link.exe
12+
# and the MSVC libraries: x86.x64 on Intel agents, ARM64 on Arm agents.
13+
# The .NET ILCompiler discovers the freshly installed toolchain through
14+
# the Visual Studio setup API, so no PATH manipulation is required.
15+
#
16+
# Intended to be invoked by a PowerShell@2 task with `filePath:` and a
17+
# single `-Architecture` argument (the matrix leg's poolArch). Diagnostics
18+
# are written to stdout so install failures can be diagnosed from the task
19+
# log.
20+
21+
param(
22+
[Parameter(Mandatory = $true)]
23+
[ValidateSet('amd64', 'arm64')]
24+
[string]$Architecture
25+
)
26+
27+
$ErrorActionPreference = 'Stop'
28+
$ProgressPreference = 'SilentlyContinue'
29+
30+
$component = if ($Architecture -eq 'arm64') {
31+
'Microsoft.VisualStudio.Component.VC.Tools.ARM64'
32+
} else {
33+
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64'
34+
}
35+
36+
$bootstrapper = "$env:TEMP\vs_BuildTools.exe"
37+
Write-Host "Downloading VS 2022 Build Tools bootstrapper..."
38+
Invoke-WebRequest -Uri 'https://aka.ms/vs/17/release/vs_BuildTools.exe' `
39+
-OutFile $bootstrapper
40+
41+
$vsArgs = @(
42+
'--quiet', '--wait', '--norestart', '--nocache',
43+
'--add', $component
44+
)
45+
Write-Host "Installing VS Build Tools (args: $($vsArgs -join ' '))..."
46+
$start = Get-Date
47+
$p = Start-Process -FilePath $bootstrapper -ArgumentList $vsArgs -Wait -PassThru
48+
$elapsed = (Get-Date) - $start
49+
Write-Host ("Installer exited with code {0} after {1:N0}s" -f `
50+
$p.ExitCode, $elapsed.TotalSeconds)
51+
52+
Write-Host ""
53+
Write-Host "===== Installer logs in `$env:TEMP ====="
54+
$logs = Get-ChildItem $env:TEMP -Filter 'dd_*.log' -ErrorAction SilentlyContinue |
55+
Sort-Object LastWriteTime -Descending
56+
if ($logs) {
57+
foreach ($log in $logs | Select-Object -First 5) {
58+
Write-Host "----- $($log.FullName) (last 50 lines) -----"
59+
Get-Content $log.FullName -Tail 50 -ErrorAction SilentlyContinue
60+
}
61+
} else {
62+
Write-Host "(no dd_*.log files found in `$env:TEMP)"
63+
}
64+
65+
# 3010 = reboot required, treated as success.
66+
if ($p.ExitCode -notin 0, 3010) {
67+
throw "VS Build Tools installer exited with code $($p.ExitCode)"
68+
}
69+
70+
Write-Host ""
71+
Write-Host "===== Confirm $component via vswhere ====="
72+
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
73+
if (Test-Path $vswhere) {
74+
$installPath = & $vswhere -latest -products * -requires $component `
75+
-property installationPath | Select-Object -First 1
76+
if ($installPath) {
77+
Write-Host "VC tools installed at $installPath"
78+
} else {
79+
throw "$component not found after install (see logs above)"
80+
}
81+
} else {
82+
Write-Host "vswhere not found at $vswhere"
83+
}

0 commit comments

Comments
 (0)