29#define WIN32_LEAN_AND_MEAN
39#define USE_MSVC_SETUP_API
46#pragma clang diagnostic push
47#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
51#pragma clang diagnostic pop
70 !EC && DirIt != DirEnd; DirIt.increment(EC)) {
78 if (Tuple > HighestTuple) {
80 Highest = CandidateName.
str();
88 const std::string &SDKPath,
89 std::string &SDKVersion) {
93 return !SDKVersion.empty();
98 std::optional<llvm::StringRef> WinSdkVersion,
99 std::optional<llvm::StringRef> WinSysRoot, std::string &Path,
int &Major,
100 std::string &Version) {
101 if (WinSdkDir || WinSysRoot) {
106 SDKVersion.
tryParse(*WinSdkVersion);
111 if (!SDKVersion.
empty())
116 Path = std::string(SDKPath.
str());
118 Path = WinSdkDir->str();
121 if (!SDKVersion.
empty()) {
133static bool readFullStringValue(HKEY hkey,
const char *valueName,
134 std::string &
value) {
135 std::wstring WideValueName;
143 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
145 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
147 std::vector<BYTE> buffer(valueSize);
148 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
150 if (result == ERROR_SUCCESS) {
151 std::wstring WideValue(
reinterpret_cast<const wchar_t *
>(buffer.data()),
152 valueSize /
sizeof(
wchar_t));
153 if (valueSize && WideValue.back() == L
'\0') {
154 WideValue.pop_back();
175 std::string &
value, std::string *phValue) {
179 HKEY hRootKey = HKEY_LOCAL_MACHINE;
182 bool returnValue =
false;
184 const char *placeHolder = strstr(keyPath,
"$VERSION");
185 std::string bestName;
188 const char *keyEnd = placeHolder - 1;
189 const char *nextKey = placeHolder;
191 while ((keyEnd > keyPath) && (*keyEnd !=
'\\'))
194 while (*nextKey && (*nextKey !=
'\\'))
196 size_t partialKeyLength = keyEnd - keyPath;
197 char partialKey[256];
198 if (partialKeyLength >=
sizeof(partialKey))
199 partialKeyLength =
sizeof(partialKey) - 1;
200 strncpy(partialKey, keyPath, partialKeyLength);
201 partialKey[partialKeyLength] =
'\0';
203 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
205 if (lResult == ERROR_SUCCESS) {
207 double bestValue = 0.0;
208 DWORD index,
size =
sizeof(keyName) - 1;
209 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &
size, NULL, NULL,
210 NULL, NULL) == ERROR_SUCCESS;
212 const char *sp = keyName;
213 while (*sp && !llvm::isDigit(*sp))
217 const char *ep = sp + 1;
218 while (*ep && (llvm::isDigit(*ep) || (*ep ==
'.')))
221 strncpy(numBuf, sp,
sizeof(numBuf) - 1);
222 numBuf[
sizeof(numBuf) - 1] =
'\0';
223 double dvalue = strtod(numBuf, NULL);
224 if (dvalue > bestValue) {
229 bestName.append(nextKey);
230 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
231 KEY_READ | KEY_WOW64_32KEY, &hKey);
232 if (lResult == ERROR_SUCCESS) {
233 if (readFullStringValue(hKey, valueName,
value)) {
242 size =
sizeof(keyName) - 1;
244 RegCloseKey(hTopKey);
248 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
249 if (lResult == ERROR_SUCCESS) {
250 if (readFullStringValue(hKey, valueName,
value))
330 path = std::string(LibPath.
str());
335 const std::string &VCToolChainPath,
338 const char *SubdirName;
339 const char *IncludeName;
343 IncludeName =
"include";
347 IncludeName =
"include";
356 if (!SubdirParent.
empty())
370 const bool HostIsX64 =
372 const char *
const HostName = HostIsX64 ?
"Hostx64" :
"Hostx86";
385 return std::string(Path.str());
393 return !VFS.
exists(TestPath);
397 std::optional<StringRef> WinSdkVersion,
398 std::optional<StringRef> WinSysRoot, std::string &Path,
399 int &Major, std::string &WindowsSDKIncludeVersion,
400 std::string &WindowsSDKLibVersion) {
403 Path, Major, WindowsSDKIncludeVersion)) {
404 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
412 std::string RegistrySDKVersion;
414 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
415 "InstallationFolder", Path, &RegistrySDKVersion))
417 if (Path.empty() || RegistrySDKVersion.empty())
420 WindowsSDKIncludeVersion.clear();
421 WindowsSDKLibVersion.clear();
423 std::sscanf(RegistrySDKVersion.c_str(),
"v%d.", &Major);
430 const char *Tests[] = {
"winv6.3",
"win8",
"win7"};
431 for (
const char *
Test : Tests) {
434 if (VFS.
exists(TestPath)) {
435 WindowsSDKLibVersion =
Test;
439 return !WindowsSDKLibVersion.empty();
444 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
452 std::optional<StringRef> WinSdkDir,
453 std::optional<StringRef> WinSdkVersion,
454 std::optional<StringRef> WinSysRoot,
455 std::string &Path, std::string &UCRTVersion) {
460 Path, Major, UCRTVersion))
469 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots",
"KitsRoot10",
477 std::optional<StringRef> VCToolsDir,
478 std::optional<StringRef> VCToolsVersion,
479 std::optional<StringRef> WinSysRoot,
483 if (VCToolsDir || WinSysRoot) {
487 std::string ToolsVersion;
489 ToolsVersion = VCToolsVersion->str();
493 Path = std::string(ToolsPath.
str());
495 Path = VCToolsDir->str();
507 if (std::optional<std::string> VCToolsInstallDir =
511 Path = std::move(*VCToolsInstallDir);
515 if (std::optional<std::string> VCInstallDir =
521 Path = std::move(*VCInstallDir);
532 for (
StringRef PathEntry : PathEntries) {
533 if (PathEntry.empty())
539 ExeTestPath = PathEntry;
541 if (!VFS.
exists(ExeTestPath))
546 ExeTestPath = PathEntry;
548 if (!VFS.
exists(ExeTestPath))
563 Path = std::string(ParentPath);
571 Path = std::string(ParentPath);
581 StringRef ExpectedPrefixes[] = {
"",
"Host",
"bin",
"",
582 "MSVC",
"Tools",
"VC"};
586 for (
StringRef Prefix : ExpectedPrefixes) {
589 if (!It->startswith_insensitive(Prefix))
597 for (
int i = 0; i < 3; ++i)
600 Path = std::string(ToolChainPath);
614#if !defined(USE_MSVC_SETUP_API)
628 struct SuppressCOMErrorsRAII {
629 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
631 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
633 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
635 } COMErrorSuppressor;
637 ISetupConfigurationPtr Query;
638 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
642 IEnumSetupInstancesPtr EnumInstances;
643 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
647 ISetupInstancePtr Instance;
648 HR = EnumInstances->Next(1, &Instance,
nullptr);
652 ISetupInstancePtr NewestInstance;
653 std::optional<uint64_t> NewestVersionNum;
655 bstr_t VersionString;
657 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
660 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
663 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
664 NewestInstance = Instance;
665 NewestVersionNum = VersionNum;
667 }
while ((HR = EnumInstances->Next(1, &Instance,
nullptr)) == S_OK);
673 HR = NewestInstance->ResolvePath(L
"VC", VCPathWide.GetAddress());
677 std::string VCRootPath;
682 "Microsoft.VCToolsVersion.default.txt");
685 if (!ToolsVersionFile)
690 ToolsVersionFile->get()->getBuffer().rtrim());
695 Path = std::string(ToolchainPath.
str());
702 std::string VSInstallPath;
704 "InstallDir", VSInstallPath,
nullptr) ||
706 "InstallDir", VSInstallPath,
nullptr)) {
707 if (!VSInstallPath.empty()) {
708 auto pos = VSInstallPath.find(R
"(\Common7\IDE)");
709 if (pos == std::string::npos)
714 Path = std::string(VCPath.
str());
This header is deprecated in favour of llvm/TargetParser/Triple.h.
Provides a library for accessing COM functionality of the Host OS.
Given that RA is a live value
static bool getSystemRegistryString(const char *keyPath, const char *valueName, std::string &value, std::string *phValue)
Read registry string.
static bool getWindowsSDKDirViaCommandLine(llvm::vfs::FileSystem &VFS, std::optional< llvm::StringRef > WinSdkDir, std::optional< llvm::StringRef > WinSdkVersion, std::optional< llvm::StringRef > WinSysRoot, std::string &Path, int &Major, std::string &Version)
static bool getWindows10SDKVersionFromPath(llvm::vfs::FileSystem &VFS, const std::string &SDKPath, std::string &SDKVersion)
static std::string getHighestNumericTupleInDirectory(llvm::vfs::FileSystem &VFS, llvm::StringRef Directory)
struct ISetupInstance2 ISetupInstance2
struct ISetupInstance ISetupInstance
struct ISetupConfiguration ISetupConfiguration
struct ISetupHelper ISetupHelper
struct ISetupConfiguration2 ISetupConfiguration2
struct IEnumSetupInstances IEnumSetupInstances
return ToRemove size() > 0
Provides a library for accessing information about this process and other processes on the operating ...
This file defines the SmallString class.
This file defines the SmallVector class.
This header is deprecated in favour of llvm/TargetParser/Host.h.
Defines the llvm::VersionTuple class, which represents a version in the form major[....
Defines the virtual file system interface vfs::FileSystem.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Triple - Helper class for working with autoconf configuration names.
ArchType getArch() const
Get the parsed architecture type of this triple.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
Represents a version number in the form major[.minor[.subminor[.build]]].
unsigned getMajor() const
Retrieve the major version number.
bool tryParse(StringRef string)
Try to parse the given string as a version number.
std::string getAsString() const
Retrieve a string representation of the version number.
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
static std::optional< std::string > GetEnv(StringRef name)
The virtual file system interface.
bool exists(const Twine &Path)
Check whether a file exists. Provided for convenience.
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
virtual llvm::ErrorOr< Status > status(const Twine &Path)=0
Get the status of the entry at Path, if one exists.
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
reverse_iterator rend(StringRef path)
Get reverse end iterator over path.
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
reverse_iterator rbegin(StringRef path, Style style=Style::native)
Get reverse begin iterator over path.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
const char EnvPathSeparator
This is the OS-specific separator for PATH like environment variables:
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
This is an optimization pass for GlobalISel generic memory operations.
const char * archToWindowsSDKArch(llvm::Triple::ArchType Arch)
bool findVCToolChainViaCommandLine(vfs::FileSystem &VFS, std::optional< llvm::StringRef > VCToolsDir, std::optional< llvm::StringRef > VCToolsVersion, std::optional< llvm::StringRef > WinSysRoot, std::string &Path, ToolsetLayout &VSLayout)
bool getWindowsSDKDir(vfs::FileSystem &VFS, std::optional< llvm::StringRef > WinSdkDir, std::optional< llvm::StringRef > WinSdkVersion, std::optional< llvm::StringRef > WinSysRoot, std::string &Path, int &Major, std::string &WindowsSDKIncludeVersion, std::string &WindowsSDKLibVersion)
Get Windows SDK installation directory.
bool useUniversalCRT(ToolsetLayout VSLayout, const std::string &VCToolChainPath, llvm::Triple::ArchType TargetArch, llvm::vfs::FileSystem &VFS)
bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path, ToolsetLayout &VSLayout)
bool convertWideToUTF8(const std::wstring &Source, std::string &Result)
Converts a std::wstring to a UTF-8 encoded std::string.
const char * archToLegacyVCArch(llvm::Triple::ArchType Arch)
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path, ToolsetLayout &VSLayout)
bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, char *&ResultPtr, const UTF8 *&ErrorPtr)
Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on WideCharWidth.
const char * archToDevDivInternalArch(llvm::Triple::ArchType Arch)
std::string getSubDirectoryPath(SubDirectoryType Type, ToolsetLayout VSLayout, const std::string &VCToolChainPath, llvm::Triple::ArchType TargetArch, llvm::StringRef SubdirParent="")
bool appendArchToWindowsSDKLibPath(int SDKMajor, llvm::SmallString< 128 > LibPath, llvm::Triple::ArchType Arch, std::string &path)
bool findVCToolChainViaRegistry(std::string &Path, ToolsetLayout &VSLayout)
bool getUniversalCRTSdkDir(vfs::FileSystem &VFS, std::optional< llvm::StringRef > WinSdkDir, std::optional< llvm::StringRef > WinSdkVersion, std::optional< llvm::StringRef > WinSysRoot, std::string &Path, std::string &UCRTVersion)