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. Reviewed by: hans Differential Revision: https://reviews.llvm.org/D145517
This commit is contained in:
parent
21700677cb
commit
af5f468228
|
@ -440,8 +440,8 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
|
|||
WinSysRoot, VCToolChainPath, VSLayout) ||
|
||||
llvm::findVCToolChainViaEnvironment(getVFS(), VCToolChainPath,
|
||||
VSLayout) ||
|
||||
llvm::findVCToolChainViaSetupConfig(getVFS(), VCToolChainPath,
|
||||
VSLayout) ||
|
||||
llvm::findVCToolChainViaSetupConfig(getVFS(), VCToolsVersion,
|
||||
VCToolChainPath, VSLayout) ||
|
||||
llvm::findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
|
||||
}
|
||||
|
||||
|
@ -546,6 +546,10 @@ bool MSVCToolChain::getWindowsSDKLibraryPath(const ArgList &Args,
|
|||
|
||||
llvm::SmallString<128> libPath(sdkPath);
|
||||
llvm::sys::path::append(libPath, "Lib");
|
||||
if (sdkMajor >= 10)
|
||||
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
|
||||
WinSdkVersion.has_value())
|
||||
windowsSDKLibVersion = *WinSdkVersion;
|
||||
if (sdkMajor >= 8)
|
||||
llvm::sys::path::append(libPath, windowsSDKLibVersion, "um");
|
||||
return llvm::appendArchToWindowsSDKLibPath(sdkMajor, libPath, getArch(),
|
||||
|
@ -567,6 +571,10 @@ bool MSVCToolChain::getUniversalCRTLibraryPath(const ArgList &Args,
|
|||
UCRTVersion))
|
||||
return false;
|
||||
|
||||
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
|
||||
WinSdkVersion.has_value())
|
||||
UCRTVersion = *WinSdkVersion;
|
||||
|
||||
StringRef ArchName = llvm::archToWindowsSDKArch(getArch());
|
||||
if (ArchName.empty())
|
||||
return false;
|
||||
|
@ -696,6 +704,9 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
|||
if (llvm::getUniversalCRTSdkDir(getVFS(), WinSdkDir, WinSdkVersion,
|
||||
WinSysRoot, UniversalCRTSdkPath,
|
||||
UCRTVersion)) {
|
||||
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
|
||||
WinSdkVersion.has_value())
|
||||
UCRTVersion = *WinSdkVersion;
|
||||
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
|
||||
"Include", UCRTVersion, "ucrt");
|
||||
}
|
||||
|
@ -708,6 +719,10 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
|||
if (llvm::getWindowsSDKDir(getVFS(), WinSdkDir, WinSdkVersion, WinSysRoot,
|
||||
WindowsSDKDir, major, windowsSDKIncludeVersion,
|
||||
windowsSDKLibVersion)) {
|
||||
if (major >= 10)
|
||||
if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
|
||||
WinSdkVersion.has_value())
|
||||
windowsSDKIncludeVersion = windowsSDKLibVersion = *WinSdkVersion;
|
||||
if (major >= 8) {
|
||||
// Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
|
||||
// Anyway, llvm::sys::path::append is able to manage it.
|
||||
|
|
|
@ -559,7 +559,7 @@ void LinkerDriver::detectWinSysRoot(const opt::InputArgList &Args) {
|
|||
WinSysRoot, vcToolChainPath, vsLayout) &&
|
||||
(Args.hasArg(OPT_lldignoreenv) ||
|
||||
!findVCToolChainViaEnvironment(*VFS, vcToolChainPath, vsLayout)) &&
|
||||
!findVCToolChainViaSetupConfig(*VFS, vcToolChainPath, vsLayout) &&
|
||||
!findVCToolChainViaSetupConfig(*VFS, {}, vcToolChainPath, vsLayout) &&
|
||||
!findVCToolChainViaRegistry(vcToolChainPath, vsLayout))
|
||||
return;
|
||||
|
||||
|
|
|
@ -90,11 +90,15 @@ bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path,
|
|||
ToolsetLayout &VSLayout);
|
||||
|
||||
// Query the Setup Config server for installs, then pick the newest version
|
||||
// and find its default VC toolchain.
|
||||
// and find its default VC toolchain. If `VCToolsVersion` is specified, that
|
||||
// version is preferred over the latest version.
|
||||
//
|
||||
// This is the preferred way to discover new Visual Studios, as they're no
|
||||
// longer listed in the registry.
|
||||
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path,
|
||||
ToolsetLayout &VSLayout);
|
||||
bool
|
||||
findVCToolChainViaSetupConfig(vfs::FileSystem &VFS,
|
||||
std::optional<llvm::StringRef> VCToolsVersion,
|
||||
std::string &Path, ToolsetLayout &VSLayout);
|
||||
|
||||
// Look in the registry for Visual Studio installs, and use that to get
|
||||
// a toolchain path. VS2017 and newer don't get added to the registry.
|
||||
|
|
|
@ -160,7 +160,7 @@ COFFVCRuntimeBootstrapper::getMSVCToolchainPath() {
|
|||
if (!findVCToolChainViaCommandLine(*VFS, std::nullopt, std::nullopt,
|
||||
std::nullopt, VCToolChainPath, VSLayout) &&
|
||||
!findVCToolChainViaEnvironment(*VFS, VCToolChainPath, VSLayout) &&
|
||||
!findVCToolChainViaSetupConfig(*VFS, VCToolChainPath, VSLayout) &&
|
||||
!findVCToolChainViaSetupConfig(*VFS, {}, VCToolChainPath, VSLayout) &&
|
||||
!findVCToolChainViaRegistry(VCToolChainPath, VSLayout))
|
||||
return make_error<StringError>("Couldn't find msvc toolchain.",
|
||||
inconvertibleErrorCode());
|
||||
|
|
|
@ -609,8 +609,9 @@ bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path,
|
||||
ToolsetLayout &VSLayout) {
|
||||
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS,
|
||||
std::optional<StringRef> VCToolsVersion,
|
||||
std::string &Path, ToolsetLayout &VSLayout) {
|
||||
#if !defined(USE_MSVC_SETUP_API)
|
||||
return false;
|
||||
#else
|
||||
|
@ -677,17 +678,24 @@ bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path,
|
|||
std::string VCRootPath;
|
||||
convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
|
||||
|
||||
SmallString<256> ToolsVersionFilePath(VCRootPath);
|
||||
sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
|
||||
"Microsoft.VCToolsVersion.default.txt");
|
||||
std::string ToolsVersion;
|
||||
if (VCToolsVersion.has_value()) {
|
||||
ToolsVersion = *VCToolsVersion;
|
||||
} else {
|
||||
SmallString<256> ToolsVersionFilePath(VCRootPath);
|
||||
sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
|
||||
"Microsoft.VCToolsVersion.default.txt");
|
||||
|
||||
auto ToolsVersionFile = MemoryBuffer::getFile(ToolsVersionFilePath);
|
||||
if (!ToolsVersionFile)
|
||||
return false;
|
||||
|
||||
ToolsVersion = ToolsVersionFile->get()->getBuffer().rtrim();
|
||||
}
|
||||
|
||||
auto ToolsVersionFile = MemoryBuffer::getFile(ToolsVersionFilePath);
|
||||
if (!ToolsVersionFile)
|
||||
return false;
|
||||
|
||||
SmallString<256> ToolchainPath(VCRootPath);
|
||||
sys::path::append(ToolchainPath, "Tools", "MSVC",
|
||||
ToolsVersionFile->get()->getBuffer().rtrim());
|
||||
sys::path::append(ToolchainPath, "Tools", "MSVC", ToolsVersion);
|
||||
auto Status = VFS.status(ToolchainPath);
|
||||
if (!Status || !Status->isDirectory())
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue
Block a user