ikudrin updated this revision to Diff 34462.
ikudrin added a comment.
- Extracted a function to convert an architecture type to a library subfolder
name.
- Added a method to check if we should use Universal CRT depending on the
chosen version of Visual Studio.
http://reviews.llvm.org/D12695
Files:
lib/Driver/MSVCToolChain.cpp
lib/Driver/ToolChains.h
lib/Driver/Tools.cpp
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -8953,6 +8953,13 @@
Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
}
+ if (MSVC.useUniversalCRT()) {
+ std::string UniversalCRTLibPath;
+ if (MSVC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
+ CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+ UniversalCRTLibPath.c_str()));
+ }
+
std::string WindowsSdkLibPath;
if (MSVC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -840,6 +840,11 @@
bool getWindowsSDKDir(std::string &path, int &major, int &minor) const;
bool getWindowsSDKLibraryPath(std::string &path) const;
+ /// \brief Check if Universal CRT should be used if available
+ bool useUniversalCRT() const;
+ bool getUniversalCRTSdkDir(std::string &path,
+ std::string &ucrtVersion) const;
+ bool getUniversalCRTLibraryPath(std::string &path) const;
bool getVisualStudioInstallDir(std::string &path) const;
bool getVisualStudioBinariesFolder(const char *clangProgramPath,
std::string &path) const;
Index: lib/Driver/MSVCToolChain.cpp
===================================================================
--- lib/Driver/MSVCToolChain.cpp
+++ lib/Driver/MSVCToolChain.cpp
@@ -205,6 +205,21 @@
#endif // USE_WIN32
}
+// Convert LLVM's ArchType
+// to the corresponding name of Windows SDK libraries subfolder
+static StringRef getWindowsSDKArch(llvm::Triple::ArchType arch) {
+ switch (arch) {
+ case llvm::Triple::x86:
+ return "x86";
+ case llvm::Triple::x86_64:
+ return "x64";
+ case llvm::Triple::arm:
+ return "arm";
+ default:
+ return "";
+ }
+}
+
/// \brief Get Windows SDK installation directory.
bool MSVCToolChain::getWindowsSDKDir(std::string &path, int &major,
int &minor) const {
@@ -263,22 +278,77 @@
if (!found)
return false;
- llvm::sys::path::append(libPath, "um");
- switch (getArch()) {
- case llvm::Triple::x86:
- llvm::sys::path::append(libPath, "x86");
- break;
- case llvm::Triple::x86_64:
- llvm::sys::path::append(libPath, "x64");
- break;
- case llvm::Triple::arm:
- llvm::sys::path::append(libPath, "arm");
- break;
- default:
+ const StringRef archName = getWindowsSDKArch(getArch());
+ if (archName.empty())
return false;
- }
+ llvm::sys::path::append(libPath, "um", archName);
+ }
+
+ path = libPath.str();
+ return true;
+}
+
+// Check if the Include path of a chosen version of Visual Studio contains
+// specific header files. If not, they are probably shipped with Universal CRT.
+bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT() const
+{
+ std::string VSDir;
+ if (!getVisualStudioInstallDir(VSDir))
+ return false;
+
+ llvm::SmallString<128> testPath(VSDir);
+ llvm::sys::path::append(testPath, "VC\\include\\stdlib.h");
+
+ return !llvm::sys::fs::exists(testPath);
+}
+
+bool MSVCToolChain::getUniversalCRTSdkDir(std::string &path,
+ std::string &ucrtVersion) const
+{
+ // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
+ // for the specific key "KitsRoot10". So do we.
+ if (!getSystemRegistryString(
+ "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots",
+ "KitsRoot10", path, nullptr))
+ return false;
+
+ ucrtVersion.clear();
+
+ // 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 name = llvm::sys::path::filename(dirIt->path());
+ if (name > ucrtVersion)
+ ucrtVersion = name;
}
+ return !ucrtVersion.empty();
+}
+
+bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &path) const
+{
+ std::string universalCRTSdkPath;
+ std::string ucrtVersion;
+
+ path.clear();
+ if (!getUniversalCRTSdkDir(universalCRTSdkPath, ucrtVersion))
+ return false;
+
+ StringRef archName = getWindowsSDKArch(getArch());
+ if (archName.empty())
+ return false;
+
+ llvm::SmallString<128> libPath(universalCRTSdkPath);
+ llvm::sys::path::append(libPath, "Lib", ucrtVersion, "ucrt", archName);
+
path = libPath.str();
return true;
}
@@ -460,6 +530,17 @@
if (getVisualStudioInstallDir(VSDir)) {
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
+ if (useUniversalCRT()) {
+ std::string universalCRTSdkPath;
+ std::string ucrtVersion;
+ if (getUniversalCRTSdkDir(universalCRTSdkPath, ucrtVersion)) {
+ llvm::SmallString<128> ucrtIncludePath(universalCRTSdkPath);
+ llvm::sys::path::append(ucrtIncludePath,
+ "Include", ucrtVersion, "ucrt");
+ addSystemInclude(DriverArgs, CC1Args, ucrtIncludePath);
+ }
+ }
+
std::string WindowsSDKDir;
int major, minor;
if (getWindowsSDKDir(WindowsSDKDir, major, minor)) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits