Skip to content

Commit bbaecec

Browse files
committed
Improve Visual Studio toolchain detection for Windows builds
1 parent d58727c commit bbaecec

2 files changed

Lines changed: 96 additions & 1 deletion

File tree

Build/Agent/FwBuildEnvironment.psm1

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,51 @@
1414
# VS Environment Functions
1515
# =============================================================================
1616

17+
function Get-PreferredVcToolBinPath {
18+
<#
19+
.SYNOPSIS
20+
Returns the preferred HostX64\x64 MSVC tool bin directory.
21+
#>
22+
if (-not $env:VCINSTALLDIR) {
23+
return $null
24+
}
25+
26+
$toolsRoot = Join-Path $env:VCINSTALLDIR 'Tools\MSVC'
27+
if (-not (Test-Path $toolsRoot)) {
28+
return $null
29+
}
30+
31+
$preferred = Get-ChildItem -Path $toolsRoot -Directory -ErrorAction SilentlyContinue |
32+
Sort-Object Name -Descending |
33+
ForEach-Object { Join-Path $_.FullName 'bin\HostX64\x64' } |
34+
Where-Object { Test-Path $_ } |
35+
Select-Object -First 1
36+
37+
return $preferred
38+
}
39+
40+
function Ensure-PreferredVcToolPath {
41+
<#
42+
.SYNOPSIS
43+
Moves the preferred HostX64\x64 MSVC bin directory to the front of PATH.
44+
#>
45+
$preferred = Get-PreferredVcToolBinPath
46+
if (-not $preferred) {
47+
return
48+
}
49+
50+
$pathEntries = @()
51+
if (-not [string]::IsNullOrWhiteSpace($env:PATH)) {
52+
$pathEntries = $env:PATH -split ';' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
53+
}
54+
55+
$filteredEntries = $pathEntries | Where-Object {
56+
-not [string]::Equals($_.TrimEnd('\'), $preferred.TrimEnd('\'), [System.StringComparison]::OrdinalIgnoreCase)
57+
}
58+
59+
$env:PATH = (@($preferred) + $filteredEntries) -join ';'
60+
}
61+
1762
function Initialize-VsDevEnvironment {
1863
<#
1964
.SYNOPSIS
@@ -27,6 +72,7 @@ function Initialize-VsDevEnvironment {
2772
}
2873

2974
if ($env:VCINSTALLDIR) {
75+
Ensure-PreferredVcToolPath
3076
Write-Host '[OK] Visual Studio environment already initialized' -ForegroundColor Green
3177
return
3278
}
@@ -87,6 +133,8 @@ function Initialize-VsDevEnvironment {
87133
throw 'Visual Studio C++ environment not configured'
88134
}
89135

136+
Ensure-PreferredVcToolPath
137+
90138
Write-Host '[OK] Visual Studio environment initialized successfully' -ForegroundColor Green
91139
Write-Host " VCINSTALLDIR: $env:VCINSTALLDIR" -ForegroundColor Gray
92140
}

Build/Src/FwBuildTasks/Make.cs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,39 @@ protected override string ToolName
111111
}
112112
}
113113

114+
private static string FindVisualStudioToolPath(string vcInstallDir, string toolName)
115+
{
116+
if (String.IsNullOrEmpty(vcInstallDir) || !Directory.Exists(vcInstallDir))
117+
return null;
118+
119+
string toolsRoot = Path.Combine(vcInstallDir, "Tools", "MSVC");
120+
if (!Directory.Exists(toolsRoot))
121+
return null;
122+
123+
string[] versionDirs = Directory.GetDirectories(toolsRoot);
124+
Array.Sort(versionDirs, StringComparer.OrdinalIgnoreCase);
125+
Array.Reverse(versionDirs);
126+
127+
foreach (string versionDir in versionDirs)
128+
{
129+
string[] candidateDirs =
130+
{
131+
Path.Combine(versionDir, "bin", "Hostx64", "x64"),
132+
Path.Combine(versionDir, "bin", "Hostx64", "x86"),
133+
Path.Combine(versionDir, "bin", "Hostx86", "x86"),
134+
Path.Combine(versionDir, "bin", "Hostx86", "x64")
135+
};
136+
137+
foreach (string candidateDir in candidateDirs)
138+
{
139+
if (File.Exists(Path.Combine(candidateDir, toolName)))
140+
return candidateDir;
141+
}
142+
}
143+
144+
return null;
145+
}
146+
114147
private void CheckToolPath()
115148
{
116149
string path = Environment.GetEnvironmentVariable("PATH");
@@ -140,7 +173,21 @@ private void CheckToolPath()
140173
// Fall Back to the install directory (if VCINSTALLDIR is set)
141174
if (!String.IsNullOrEmpty(vcInstallDir))
142175
{
143-
ToolPath = Path.Combine(vcInstallDir, "bin");
176+
string visualStudioToolPath = FindVisualStudioToolPath(vcInstallDir, ToolName);
177+
if (!String.IsNullOrEmpty(visualStudioToolPath))
178+
{
179+
ToolPath = visualStudioToolPath;
180+
return;
181+
}
182+
183+
string legacyToolPath = Path.Combine(vcInstallDir, "bin");
184+
if (File.Exists(Path.Combine(legacyToolPath, ToolName)))
185+
{
186+
ToolPath = legacyToolPath;
187+
return;
188+
}
189+
190+
ToolPath = String.Empty;
144191
}
145192
else
146193
{

0 commit comments

Comments
 (0)