ikudrin updated this revision to Diff 34465.
ikudrin marked an inline comment as done.
ikudrin added a comment.

Just added more context to the patch.


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
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to