Skip to content

Commit 182eec0

Browse files
committed
MSVC: support version preference with search
Extend the logic for the WinSDK and UCRT handling to prefer a user specified version of the VisualC++ tools and Windows SDK. This allows us to now perform the regular search for the installation but select the exact version of the SDK or VC++ tools to override the latest version. Similar to the other flags controlling this behaviour, if the user specifies a value, we will not perform validation on the input and will attempt to prefer that, particularly in the case of VisualC++ tools where no fallback occurs.
1 parent e19f350 commit 182eec0

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

clang/lib/Driver/ToolChains/MSVC.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,8 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
430430
WinSysRoot, VCToolChainPath, VSLayout) ||
431431
llvm::findVCToolChainViaEnvironment(getVFS(), VCToolChainPath,
432432
VSLayout) ||
433-
llvm::findVCToolChainViaSetupConfig(getVFS(), VCToolChainPath,
434-
VSLayout) ||
433+
llvm::findVCToolChainViaSetupConfig(getVFS(), VCToolsVersion,
434+
VCToolChainPath, VSLayout) ||
435435
llvm::findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
436436
}
437437

@@ -536,6 +536,10 @@ bool MSVCToolChain::getWindowsSDKLibraryPath(const ArgList &Args,
536536

537537
llvm::SmallString<128> libPath(sdkPath);
538538
llvm::sys::path::append(libPath, "Lib");
539+
if (sdkMajor >= 10)
540+
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
541+
WinSdkVersion.has_value())
542+
windowsSDKLibVersion = *WinSdkVersion;
539543
if (sdkMajor >= 8)
540544
llvm::sys::path::append(libPath, windowsSDKLibVersion, "um");
541545
return llvm::appendArchToWindowsSDKLibPath(sdkMajor, libPath, getArch(),
@@ -557,6 +561,10 @@ bool MSVCToolChain::getUniversalCRTLibraryPath(const ArgList &Args,
557561
UCRTVersion))
558562
return false;
559563

564+
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
565+
WinSdkVersion.has_value())
566+
UCRTVersion = *WinSdkVersion;
567+
560568
StringRef ArchName = llvm::archToWindowsSDKArch(getArch());
561569
if (ArchName.empty())
562570
return false;
@@ -686,6 +694,9 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
686694
if (llvm::getUniversalCRTSdkDir(getVFS(), WinSdkDir, WinSdkVersion,
687695
WinSysRoot, UniversalCRTSdkPath,
688696
UCRTVersion)) {
697+
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
698+
WinSdkVersion.has_value())
699+
UCRTVersion = *WinSdkVersion;
689700
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
690701
"Include", UCRTVersion, "ucrt");
691702
}
@@ -698,6 +709,10 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
698709
if (llvm::getWindowsSDKDir(getVFS(), WinSdkDir, WinSdkVersion, WinSysRoot,
699710
WindowsSDKDir, major, windowsSDKIncludeVersion,
700711
windowsSDKLibVersion)) {
712+
if (major >= 10)
713+
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
714+
WinSdkVersion.has_value())
715+
windowsSDKIncludeVersion = windowsSDKLibVersion = *WinSdkVersion;
701716
if (major >= 8) {
702717
// Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
703718
// Anyway, llvm::sys::path::append is able to manage it.

lld/COFF/Driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ void LinkerDriver::detectWinSysRoot(const opt::InputArgList &Args) {
560560
WinSysRoot, vcToolChainPath, vsLayout) &&
561561
(Args.hasArg(OPT_lldignoreenv) ||
562562
!findVCToolChainViaEnvironment(*VFS, vcToolChainPath, vsLayout)) &&
563-
!findVCToolChainViaSetupConfig(*VFS, vcToolChainPath, vsLayout) &&
563+
!findVCToolChainViaSetupConfig(*VFS, {}, vcToolChainPath, vsLayout) &&
564564
!findVCToolChainViaRegistry(vcToolChainPath, vsLayout))
565565
return;
566566

llvm/include/llvm/WindowsDriver/MSVCPaths.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,15 @@ bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path,
9191
ToolsetLayout &VSLayout);
9292

9393
// Query the Setup Config server for installs, then pick the newest version
94-
// and find its default VC toolchain.
94+
// and find its default VC toolchain. If `VCToolsVersion` is specified, that
95+
// version is preferred over the latest version.
96+
//
9597
// This is the preferred way to discover new Visual Studios, as they're no
9698
// longer listed in the registry.
97-
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path,
98-
ToolsetLayout &VSLayout);
99+
bool
100+
findVCToolChainViaSetupConfig(vfs::FileSystem &VFS,
101+
llvm::Optional<llvm::StringRef> VCToolsVersion,
102+
std::string &Path, ToolsetLayout &VSLayout);
99103

100104
// Look in the registry for Visual Studio installs, and use that to get
101105
// a toolchain path. VS2017 and newer don't get added to the registry.

llvm/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ COFFVCRuntimeBootstrapper::getMSVCToolchainPath() {
160160
if (!findVCToolChainViaCommandLine(*VFS, None, None, None, VCToolChainPath,
161161
VSLayout) &&
162162
!findVCToolChainViaEnvironment(*VFS, VCToolChainPath, VSLayout) &&
163-
!findVCToolChainViaSetupConfig(*VFS, VCToolChainPath, VSLayout) &&
163+
!findVCToolChainViaSetupConfig(*VFS, {}, VCToolChainPath, VSLayout) &&
164164
!findVCToolChainViaRegistry(VCToolChainPath, VSLayout))
165165
return make_error<StringError>("Couldn't find msvc toolchain.",
166166
inconvertibleErrorCode());

llvm/lib/WindowsDriver/MSVCPaths.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,9 @@ bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path,
608608
return false;
609609
}
610610

611-
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path,
612-
ToolsetLayout &VSLayout) {
611+
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS,
612+
Optional<StringRef> VCToolsVersion,
613+
std::string &Path, ToolsetLayout &VSLayout) {
613614
#if !defined(USE_MSVC_SETUP_API)
614615
return false;
615616
#else
@@ -676,17 +677,23 @@ bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path,
676677
std::string VCRootPath;
677678
convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
678679

679-
SmallString<256> ToolsVersionFilePath(VCRootPath);
680-
sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
681-
"Microsoft.VCToolsVersion.default.txt");
680+
std::string ToolsVersion;
681+
if (VCToolsVersion.has_value()) {
682+
ToolsVersion = *VCToolsVersion;
683+
} else {
684+
SmallString<256> ToolsVersionFilePath(VCRootPath);
685+
sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
686+
"Microsoft.VCToolsVersion.default.txt");
687+
688+
auto ToolsVersionFile = MemoryBuffer::getFile(ToolsVersionFilePath);
689+
if (!ToolsVersionFile)
690+
return false;
682691

683-
auto ToolsVersionFile = MemoryBuffer::getFile(ToolsVersionFilePath);
684-
if (!ToolsVersionFile)
685-
return false;
692+
ToolsVersion = ToolsVersionFile->get()->getBuffer().rtrim();
693+
}
686694

687695
SmallString<256> ToolchainPath(VCRootPath);
688-
sys::path::append(ToolchainPath, "Tools", "MSVC",
689-
ToolsVersionFile->get()->getBuffer().rtrim());
696+
sys::path::append(ToolchainPath, "Tools", "MSVC", ToolsVersion);
690697
auto Status = VFS.status(ToolchainPath);
691698
if (!Status || !Status->isDirectory())
692699
return false;

0 commit comments

Comments
 (0)