r248463 - [Driver] Add support for Windows 10 SDK

Igor Kudrin via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 23 22:16:36 PDT 2015


Author: ikudrin
Date: Thu Sep 24 00:16:36 2015
New Revision: 248463

URL: http://llvm.org/viewvc/llvm-project?rev=248463&view=rev
Log:
[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

Modified:
    cfe/trunk/lib/Driver/MSVCToolChain.cpp
    cfe/trunk/lib/Driver/ToolChains.h

Modified: cfe/trunk/lib/Driver/MSVCToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/MSVCToolChain.cpp?rev=248463&r1=248462&r2=248463&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/MSVCToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/MSVCToolChain.cpp Thu Sep 24 00:16:36 2015
@@ -220,27 +220,88 @@ static StringRef getWindowsSDKArch(llvm:
   }
 }
 
+// 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.
-bool MSVCToolChain::getWindowsSDKDir(std::string &path, int &major,
-                                     int &minor) const {
-  std::string sdkVersion;
+bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
+                                     std::string &WindowsSDKIncludeVersion,
+                                     std::string &WindowsSDKLibVersion) const {
+  std::string RegistrySDKVersion;
   // Try the Windows registry.
-  bool hasSDKDir = getSystemRegistryString(
-      "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
-      "InstallationFolder", path, &sdkVersion);
-  if (!sdkVersion.empty())
-    std::sscanf(sdkVersion.c_str(), "v%d.%d", &major, &minor);
-  return hasSDKDir && !path.empty();
+  if (!getSystemRegistryString(
+          "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
+          "InstallationFolder", Path, &RegistrySDKVersion))
+    return false;
+  if (Path.empty() || RegistrySDKVersion.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.
 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
   std::string sdkPath;
   int sdkMajor = 0;
-  int sdkMinor = 0;
+  std::string windowsSDKIncludeVersion;
+  std::string windowsSDKLibVersion;
 
   path.clear();
-  if (!getWindowsSDKDir(sdkPath, sdkMajor, sdkMinor))
+  if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
+                        windowsSDKLibVersion))
     return false;
 
   llvm::SmallString<128> libPath(sdkPath);
@@ -260,28 +321,10 @@ bool MSVCToolChain::getWindowsSDKLibrary
       return false;
     }
   } 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());
     if (archName.empty())
       return false;
-    llvm::sys::path::append(libPath, "um", archName);
+    llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
   }
 
   path = libPath.str();
@@ -307,25 +350,7 @@ bool MSVCToolChain::getUniversalCRTSdkDi
           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();
+  return getWindows10SDKVersion(Path, UCRTVersion);
 }
 
 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
@@ -483,12 +508,12 @@ bool MSVCToolChain::getVisualStudioInsta
   return false;
 }
 
-void MSVCToolChain::AddSystemIncludeWithSubfolder(const ArgList &DriverArgs,
-                                                  ArgStringList &CC1Args,
-                                                  const std::string &folder,
-                                                  const char *subfolder) const {
+void MSVCToolChain::AddSystemIncludeWithSubfolder(
+    const ArgList &DriverArgs, ArgStringList &CC1Args,
+    const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
+    const Twine &subfolder3) const {
   llvm::SmallString<128> path(folder);
-  llvm::sys::path::append(path, subfolder);
+  llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
   addSystemInclude(DriverArgs, CC1Args, path);
 }
 
@@ -498,9 +523,8 @@ void MSVCToolChain::AddClangSystemInclud
     return;
 
   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    SmallString<128> P(getDriver().ResourceDir);
-    llvm::sys::path::append(P, "include");
-    addSystemInclude(DriverArgs, CC1Args, P);
+    AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
+                                  "include");
   }
 
   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
@@ -528,23 +552,29 @@ void MSVCToolChain::AddClangSystemInclud
       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);
+        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
+                                      "Include", UCRTVersion, "ucrt");
       }
     }
 
     std::string WindowsSDKDir;
-    int major, minor;
-    if (getWindowsSDKDir(WindowsSDKDir, major, minor)) {
+    int major;
+    std::string windowsSDKIncludeVersion;
+    std::string windowsSDKLibVersion;
+    if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
+                         windowsSDKLibVersion)) {
       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,
-                                      "include\\shared");
+                                      "include", windowsSDKIncludeVersion,
+                                      "shared");
         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
-                                      "include\\um");
+                                      "include", windowsSDKIncludeVersion,
+                                      "um");
         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
-                                      "include\\winrt");
+                                      "include", windowsSDKIncludeVersion,
+                                      "winrt");
       } else {
         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
                                       "include");

Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=248463&r1=248462&r2=248463&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Thu Sep 24 00:16:36 2015
@@ -871,7 +871,9 @@ public:
       const llvm::opt::ArgList &DriverArgs,
       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;
   /// \brief Check if Universal CRT should be used if available
   bool useUniversalCRT(std::string &visualStudioDir) const;
@@ -889,7 +891,9 @@ protected:
   void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
                                      llvm::opt::ArgStringList &CC1Args,
                                      const std::string &folder,
-                                     const char *subfolder) const;
+                                     const Twine &subfolder1,
+                                     const Twine &subfolder2 = "",
+                                     const Twine &subfolder3 = "") const;
 
   Tool *buildLinker() const override;
   Tool *buildAssembler() const override;




More information about the cfe-commits mailing list