[Driver] Add support for Windows 10 SDK
Summary: With Windows 10 SDK, Include and Lib directories now contain an additional subfolder with the name that corresponds to the full version of the SDK, for example: - C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\um - C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x64 Reviewers: ruiu, rnk Subscribers: majnemer, cfe-commits Differential Revision: http://reviews.llvm.org/D12832 llvm-svn: 248463
This commit is contained in:
parent
49655f806f
commit
f2e7524356
|
|
@ -220,27 +220,88 @@ static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the most recent version of Universal CRT or Windows 10 SDK.
|
||||||
|
// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
|
||||||
|
// directory by name and uses the last one of the list.
|
||||||
|
// So we compare entry names lexicographically to find the greatest one.
|
||||||
|
static bool getWindows10SDKVersion(const std::string &SDKPath,
|
||||||
|
std::string &SDKVersion) {
|
||||||
|
SDKVersion.clear();
|
||||||
|
|
||||||
|
std::error_code EC;
|
||||||
|
llvm::SmallString<128> IncludePath(SDKPath);
|
||||||
|
llvm::sys::path::append(IncludePath, "Include");
|
||||||
|
for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
|
||||||
|
DirIt != DirEnd && !EC; DirIt.increment(EC)) {
|
||||||
|
if (!llvm::sys::fs::is_directory(DirIt->path()))
|
||||||
|
continue;
|
||||||
|
StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
|
||||||
|
// If WDK is installed, there could be subfolders like "wdf" in the
|
||||||
|
// "Include" directory.
|
||||||
|
// Allow only directories which names start with "10.".
|
||||||
|
if (!CandidateName.startswith("10."))
|
||||||
|
continue;
|
||||||
|
if (CandidateName > SDKVersion)
|
||||||
|
SDKVersion = CandidateName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !SDKVersion.empty();
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Get Windows SDK installation directory.
|
/// \brief Get Windows SDK installation directory.
|
||||||
bool MSVCToolChain::getWindowsSDKDir(std::string &path, int &major,
|
bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
|
||||||
int &minor) const {
|
std::string &WindowsSDKIncludeVersion,
|
||||||
std::string sdkVersion;
|
std::string &WindowsSDKLibVersion) const {
|
||||||
|
std::string RegistrySDKVersion;
|
||||||
// Try the Windows registry.
|
// Try the Windows registry.
|
||||||
bool hasSDKDir = getSystemRegistryString(
|
if (!getSystemRegistryString(
|
||||||
"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
|
"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
|
||||||
"InstallationFolder", path, &sdkVersion);
|
"InstallationFolder", Path, &RegistrySDKVersion))
|
||||||
if (!sdkVersion.empty())
|
return false;
|
||||||
std::sscanf(sdkVersion.c_str(), "v%d.%d", &major, &minor);
|
if (Path.empty() || RegistrySDKVersion.empty())
|
||||||
return hasSDKDir && !path.empty();
|
return false;
|
||||||
|
|
||||||
|
WindowsSDKIncludeVersion.clear();
|
||||||
|
WindowsSDKLibVersion.clear();
|
||||||
|
Major = 0;
|
||||||
|
std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
|
||||||
|
if (Major <= 7)
|
||||||
|
return true;
|
||||||
|
if (Major == 8) {
|
||||||
|
// Windows SDK 8.x installs libraries in a folder whose names depend on the
|
||||||
|
// version of the OS you're targeting. By default choose the newest, which
|
||||||
|
// usually corresponds to the version of the OS you've installed the SDK on.
|
||||||
|
const char *Tests[] = {"winv6.3", "win8", "win7"};
|
||||||
|
for (const char *Test : Tests) {
|
||||||
|
llvm::SmallString<128> TestPath(Path);
|
||||||
|
llvm::sys::path::append(TestPath, "Lib", Test);
|
||||||
|
if (llvm::sys::fs::exists(TestPath.c_str())) {
|
||||||
|
WindowsSDKLibVersion = Test;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !WindowsSDKLibVersion.empty();
|
||||||
|
}
|
||||||
|
if (Major == 10) {
|
||||||
|
if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
|
||||||
|
return false;
|
||||||
|
WindowsSDKLibVersion = WindowsSDKIncludeVersion;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Unsupported SDK version
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the library path required to link against the Windows SDK.
|
// Gets the library path required to link against the Windows SDK.
|
||||||
bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
|
bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
|
||||||
std::string sdkPath;
|
std::string sdkPath;
|
||||||
int sdkMajor = 0;
|
int sdkMajor = 0;
|
||||||
int sdkMinor = 0;
|
std::string windowsSDKIncludeVersion;
|
||||||
|
std::string windowsSDKLibVersion;
|
||||||
|
|
||||||
path.clear();
|
path.clear();
|
||||||
if (!getWindowsSDKDir(sdkPath, sdkMajor, sdkMinor))
|
if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
|
||||||
|
windowsSDKLibVersion))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
llvm::SmallString<128> libPath(sdkPath);
|
llvm::SmallString<128> libPath(sdkPath);
|
||||||
|
|
@ -260,28 +321,10 @@ bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Windows SDK 8.x installs libraries in a folder whose names depend on the
|
|
||||||
// version of the OS you're targeting. By default choose the newest, which
|
|
||||||
// usually corresponds to the version of the OS you've installed the SDK on.
|
|
||||||
const char *tests[] = {"winv6.3", "win8", "win7"};
|
|
||||||
bool found = false;
|
|
||||||
for (const char *test : tests) {
|
|
||||||
llvm::SmallString<128> testPath(libPath);
|
|
||||||
llvm::sys::path::append(testPath, test);
|
|
||||||
if (llvm::sys::fs::exists(testPath.c_str())) {
|
|
||||||
libPath = testPath;
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const StringRef archName = getWindowsSDKArch(getArch());
|
const StringRef archName = getWindowsSDKArch(getArch());
|
||||||
if (archName.empty())
|
if (archName.empty())
|
||||||
return false;
|
return false;
|
||||||
llvm::sys::path::append(libPath, "um", archName);
|
llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = libPath.str();
|
path = libPath.str();
|
||||||
|
|
@ -307,25 +350,7 @@ bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
|
||||||
Path, nullptr))
|
Path, nullptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
UCRTVersion.clear();
|
return getWindows10SDKVersion(Path, UCRTVersion);
|
||||||
|
|
||||||
// Find the most recent version of Universal CRT.
|
|
||||||
// vcvarsqueryregistry.bat sorts entries in the include directory by names and
|
|
||||||
// uses the last one of the list.
|
|
||||||
// So we compare entry names lexicographically to find the greatest one.
|
|
||||||
std::error_code EC;
|
|
||||||
llvm::SmallString<128> IncludePath(Path);
|
|
||||||
llvm::sys::path::append(IncludePath, "Include");
|
|
||||||
for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
|
|
||||||
DirIt != DirEnd && !EC; DirIt.increment(EC)) {
|
|
||||||
if (!llvm::sys::fs::is_directory(DirIt->path()))
|
|
||||||
continue;
|
|
||||||
StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
|
|
||||||
if (CandidateName > UCRTVersion)
|
|
||||||
UCRTVersion = CandidateName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !UCRTVersion.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
|
bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
|
||||||
|
|
@ -483,12 +508,12 @@ bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSVCToolChain::AddSystemIncludeWithSubfolder(const ArgList &DriverArgs,
|
void MSVCToolChain::AddSystemIncludeWithSubfolder(
|
||||||
ArgStringList &CC1Args,
|
const ArgList &DriverArgs, ArgStringList &CC1Args,
|
||||||
const std::string &folder,
|
const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
|
||||||
const char *subfolder) const {
|
const Twine &subfolder3) const {
|
||||||
llvm::SmallString<128> path(folder);
|
llvm::SmallString<128> path(folder);
|
||||||
llvm::sys::path::append(path, subfolder);
|
llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
|
||||||
addSystemInclude(DriverArgs, CC1Args, path);
|
addSystemInclude(DriverArgs, CC1Args, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -498,9 +523,8 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
|
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
|
||||||
SmallString<128> P(getDriver().ResourceDir);
|
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
|
||||||
llvm::sys::path::append(P, "include");
|
"include");
|
||||||
addSystemInclude(DriverArgs, CC1Args, P);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
|
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
|
||||||
|
|
@ -528,23 +552,29 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||||
std::string UniversalCRTSdkPath;
|
std::string UniversalCRTSdkPath;
|
||||||
std::string UCRTVersion;
|
std::string UCRTVersion;
|
||||||
if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
|
if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
|
||||||
llvm::SmallString<128> UCRTIncludePath(UniversalCRTSdkPath);
|
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
|
||||||
llvm::sys::path::append(UCRTIncludePath, "Include", UCRTVersion,
|
"Include", UCRTVersion, "ucrt");
|
||||||
"ucrt");
|
|
||||||
addSystemInclude(DriverArgs, CC1Args, UCRTIncludePath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WindowsSDKDir;
|
std::string WindowsSDKDir;
|
||||||
int major, minor;
|
int major;
|
||||||
if (getWindowsSDKDir(WindowsSDKDir, major, minor)) {
|
std::string windowsSDKIncludeVersion;
|
||||||
|
std::string windowsSDKLibVersion;
|
||||||
|
if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
|
||||||
|
windowsSDKLibVersion)) {
|
||||||
if (major >= 8) {
|
if (major >= 8) {
|
||||||
|
// Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
|
||||||
|
// Anyway, llvm::sys::path::append is able to manage it.
|
||||||
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
||||||
"include\\shared");
|
"include", windowsSDKIncludeVersion,
|
||||||
|
"shared");
|
||||||
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
||||||
"include\\um");
|
"include", windowsSDKIncludeVersion,
|
||||||
|
"um");
|
||||||
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
||||||
"include\\winrt");
|
"include", windowsSDKIncludeVersion,
|
||||||
|
"winrt");
|
||||||
} else {
|
} else {
|
||||||
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
|
||||||
"include");
|
"include");
|
||||||
|
|
|
||||||
|
|
@ -871,7 +871,9 @@ public:
|
||||||
const llvm::opt::ArgList &DriverArgs,
|
const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const override;
|
llvm::opt::ArgStringList &CC1Args) const override;
|
||||||
|
|
||||||
bool getWindowsSDKDir(std::string &path, int &major, int &minor) const;
|
bool getWindowsSDKDir(std::string &path, int &major,
|
||||||
|
std::string &windowsSDKIncludeVersion,
|
||||||
|
std::string &windowsSDKLibVersion) const;
|
||||||
bool getWindowsSDKLibraryPath(std::string &path) const;
|
bool getWindowsSDKLibraryPath(std::string &path) const;
|
||||||
/// \brief Check if Universal CRT should be used if available
|
/// \brief Check if Universal CRT should be used if available
|
||||||
bool useUniversalCRT(std::string &visualStudioDir) const;
|
bool useUniversalCRT(std::string &visualStudioDir) const;
|
||||||
|
|
@ -889,7 +891,9 @@ protected:
|
||||||
void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
|
void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args,
|
llvm::opt::ArgStringList &CC1Args,
|
||||||
const std::string &folder,
|
const std::string &folder,
|
||||||
const char *subfolder) const;
|
const Twine &subfolder1,
|
||||||
|
const Twine &subfolder2 = "",
|
||||||
|
const Twine &subfolder3 = "") const;
|
||||||
|
|
||||||
Tool *buildLinker() const override;
|
Tool *buildLinker() const override;
|
||||||
Tool *buildAssembler() const override;
|
Tool *buildAssembler() const override;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue