r247362 - [Driver] Use UniversalCRT on Windows if available
Reid Kleckner via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 10 17:09:39 PDT 2015
Author: rnk
Date: Thu Sep 10 19:09:39 2015
New Revision: 247362
URL: http://llvm.org/viewvc/llvm-project?rev=247362&view=rev
Log:
[Driver] Use UniversalCRT on Windows if available
Summary:
With Visual Studio 2015 release, a part of runtime library was extracted
and now comes with Windows Kits. This patch enables clang to use
Universal CRT library if %INCLUDE or %LIB environment varaibles are not
specified.
See also https://llvm.org/bugs/show_bug.cgi?id=24741
Patch by Igor Kudrin
Reviewers: zturner, hans, rnk
Subscribers: ruiu, cfe-commits
Differential Revision: http://reviews.llvm.org/D12695
Modified:
cfe/trunk/lib/Driver/MSVCToolChain.cpp
cfe/trunk/lib/Driver/ToolChains.h
cfe/trunk/lib/Driver/Tools.cpp
Modified: cfe/trunk/lib/Driver/MSVCToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/MSVCToolChain.cpp?rev=247362&r1=247361&r2=247362&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/MSVCToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/MSVCToolChain.cpp Thu Sep 10 19:09:39 2015
@@ -205,6 +205,21 @@ static bool getSystemRegistryString(cons
#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,26 +278,75 @@ bool MSVCToolChain::getWindowsSDKLibrary
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 specified version of Visual Studio contains
+// specific header files. If not, they are probably shipped with Universal CRT.
+bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
+ std::string &VisualStudioDir) const {
+ llvm::SmallString<128> TestPath(VisualStudioDir);
+ 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 CandidateName = llvm::sys::path::filename(DirIt->path());
+ if (CandidateName > UCRTVersion)
+ UCRTVersion = CandidateName;
+ }
+
+ 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;
+}
+
// Get the location to use for Visual Studio binaries. The location priority
// is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
// system (as reported by the registry).
@@ -460,6 +524,17 @@ void MSVCToolChain::AddClangSystemInclud
if (getVisualStudioInstallDir(VSDir)) {
AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
+ if (useUniversalCRT(VSDir)) {
+ 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)) {
Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=247362&r1=247361&r2=247362&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Thu Sep 10 19:09:39 2015
@@ -840,6 +840,10 @@ public:
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(std::string &visualStudioDir) 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;
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=247362&r1=247361&r2=247362&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Thu Sep 10 19:09:39 2015
@@ -8948,6 +8948,13 @@ void visualstudio::Linker::ConstructJob(
}
CmdArgs.push_back(
Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
+
+ if (MSVC.useUniversalCRT(VisualStudioDir)) {
+ std::string UniversalCRTLibPath;
+ if (MSVC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
+ CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+ UniversalCRTLibPath.c_str()));
+ }
}
std::string WindowsSdkLibPath;
More information about the cfe-commits
mailing list