ikudrin created this revision.
ikudrin added a subscriber: cfe-commits.

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

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,11 @@
           Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
     }
 
+    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
@@ -836,6 +836,9 @@
 
   bool getWindowsSDKDir(std::string &path, int &major, int &minor) const;
   bool getWindowsSDKLibraryPath(std::string &path) 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
@@ -283,6 +283,66 @@
   return true;
 }
 
+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;
+
+  llvm::SmallString<128> libPath(universalCRTSdkPath);
+  llvm::sys::path::append(libPath, "Lib", ucrtVersion, "ucrt");
+  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:
+    return false;
+  }
+
+  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 +520,14 @@
   if (getVisualStudioInstallDir(VSDir)) {
     AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
 
+    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
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to