[cfe-dev] Version agnostic path search for mingw

Nikola Smiljanic popizdeh at gmail.com
Tue Mar 20 16:05:40 PDT 2012


Here's a patch that factors out the common code. Everything that had a
version now calls AddVersionedCPlusPlusIncludes,
AddGnuCPlusPlusIncludes is used for paths that don't mention version
numbers, and C includes for mingw are specific enough to have their
own function.

The main issue that I see with this is that it's too specific. It just
covers the cases that were already there. I would leave the generic
solution to someone who knows the path issues better than me. If this
is not the right approach I will go back to the previous patch and
just submit the mingw fixes.
-------------- next part --------------
Index: lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- lib/Frontend/InitHeaderSearch.cpp	(revision 153147)
+++ lib/Frontend/InitHeaderSearch.cpp	(working copy)
@@ -24,7 +24,9 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Regex.h"
 
 #include "clang/Config/config.h" // C_INCLUDE_DIRS
 
@@ -57,25 +59,17 @@
                bool isCXXAware, bool isUserSupplied,
                bool isFramework, bool IgnoreSysRoot = false);
 
-  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
-  ///  libstdc++.
-  void AddGnuCPlusPlusIncludePaths(StringRef Base,
-                                   StringRef ArchDir,
-                                   StringRef Dir32,
-                                   StringRef Dir64,
-                                   const llvm::Triple &triple);
+  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths for gnu libstdc++.
+  void AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir);
+  
+  /// AddVersionedCPlusPlusIncludePaths - Add paths with version number
+  void AddVersionedCPlusPlusIncludePaths(StringRef Base, 
+                                         StringRef Suffix, 
+                                         StringRef Arch);
 
-  /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
-  ///  libstdc++.
-  void AddMinGWCPlusPlusIncludePaths(StringRef Base,
-                                     StringRef Arch,
-                                     StringRef Version);
+  /// AddMinGWCIncludePaths - Add MinGW paths that should always be searched
+  void AddMinGWCIncludePaths(StringRef Base);
 
-  /// AddMinGW64CXXPaths - Add the necessary paths to support
-  /// libstdc++ of x86_64-w64-mingw32 aka mingw-w64.
-  void AddMinGW64CXXPaths(StringRef Base,
-                          StringRef Version);
-
   // AddDefaultCIncludePaths - Add paths that should always be searched.
   void AddDefaultCIncludePaths(const llvm::Triple &triple,
                                const HeaderSearchOptions &HSOpts);
@@ -159,47 +153,49 @@
 }
 
 void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
-                                                   StringRef ArchDir,
-                                                   StringRef Dir32,
-                                                   StringRef Dir64,
-                                                   const llvm::Triple &triple) {
-  // Add the base dir
+                                                   StringRef ArchDir) {
   AddPath(Base, CXXSystem, true, false, false);
-
-  // Add the multilib dirs
-  llvm::Triple::ArchType arch = triple.getArch();
-  bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
-  if (is64bit)
-    AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, true, false, false);
-  else
-    AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, true, false, false);
-
-  // Add the backward dir
+  AddPath(Base + "/" + ArchDir, CXXSystem, true, false, false);
   AddPath(Base + "/backward", CXXSystem, true, false, false);
 }
 
-void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
-                                                     StringRef Arch,
-                                                     StringRef Version) {
-  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
-          CXXSystem, true, false, false);
-  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch,
-          CXXSystem, true, false, false);
-  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
-          CXXSystem, true, false, false);
+void InitHeaderSearch::AddVersionedCPlusPlusIncludePaths(StringRef Base, 
+                                                         StringRef Suffix,
+                                                         StringRef Arch) {
+  llvm::error_code EC;
+  // match directories of the forms x.x and x.x.x where x can be 1 or 2 digits
+  llvm::Regex Regex("[0-9]{1,2}\\.[0-9]{1,2}(\\.[0-9]{1,2})?$");
+  // Assumes Base is HeaderSearchOpts' ResourceDir
+  for (llvm::sys::fs::directory_iterator Dir(Base, EC), DirEnd;
+    Dir != DirEnd && !EC; Dir.increment(EC)) {
+      llvm::sys::fs::file_status status;
+      if (!Dir->status(status) && 
+          is_directory(status) && 
+          Regex.match(Dir->path())) {
+        AddPath(Dir->path() + Suffix, CXXSystem, true, false, false);
+        AddPath(Dir->path() + Suffix + Arch, CXXSystem, true, false, false);
+        AddPath(Dir->path() + Suffix + "/backward", 
+                CXXSystem, true, false, false);
+      }
+  }
 }
 
-void InitHeaderSearch::AddMinGW64CXXPaths(StringRef Base,
-                                          StringRef Version) {
-  // Assumes Base is HeaderSearchOpts' ResourceDir
-  AddPath(Base + "/../../../include/c++/" + Version,
-          CXXSystem, true, false, false);
-  AddPath(Base + "/../../../include/c++/" + Version + "/x86_64-w64-mingw32",
-          CXXSystem, true, false, false);
-  AddPath(Base + "/../../../include/c++/" + Version + "/i686-w64-mingw32",
-          CXXSystem, true, false, false);
-  AddPath(Base + "/../../../include/c++/" + Version + "/backward",
-          CXXSystem, true, false, false);
+void InitHeaderSearch::AddMinGWCIncludePaths(StringRef Base)
+{
+  llvm::error_code EC;
+  // match directories of the forms x.x and x.x.x where x can be 1 or 2 digits
+  llvm::Regex Regex("[0-9]{1,2}\\.[0-9]{1,2}(\\.[0-9]{1,2})?$");
+  for (llvm::sys::fs::directory_iterator Dir(Base + "/lib/gcc/mingw32", EC), 
+       DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) {
+      llvm::sys::fs::file_status status;
+      if (!Dir->status(status) && 
+          is_directory(status) && 
+          Regex.match(Dir->path())) {
+        AddPath(Dir->path() + "/include", System, true, false, false);
+        AddPath(Base + "/" + "include", System, true, false, false);
+        AddPath(Dir->path() + "/include-fixed", System, true, false, false);
+      }
+  }
 }
 
 void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
@@ -301,17 +297,19 @@
   case llvm::Triple::MinGW32: { 
       // mingw-w64 crt include paths
       llvm::sys::Path P(HSOpts.ResourceDir);
-      P.appendComponent("../../../i686-w64-mingw32/include"); // <sysroot>/i686-w64-mingw32/include
+      // <sysroot>/i686-w64-mingw32/include
+      P.appendComponent("../../../i686-w64-mingw32/include");
       AddPath(P.str(), System, true, false, false);
       P = llvm::sys::Path(HSOpts.ResourceDir);
-      P.appendComponent("../../../x86_64-w64-mingw32/include"); // <sysroot>/x86_64-w64-mingw32/include
+      // <sysroot>/x86_64-w64-mingw32/include
+      P.appendComponent("../../../x86_64-w64-mingw32/include");
       AddPath(P.str(), System, true, false, false);
       // mingw.org crt include paths
       P = llvm::sys::Path(HSOpts.ResourceDir);
       P.appendComponent("../../../include"); // <sysroot>/include
       AddPath(P.str(), System, true, false, false);
       AddPath("/mingw/include", System, true, false, false);
-      AddPath("c:/mingw/include", System, true, false, false); 
+      AddMinGWCIncludePaths("c:/mingw");
     }
     break;
       
@@ -324,7 +322,8 @@
 }
 
 void InitHeaderSearch::
-AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) {
+AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, 
+                                const HeaderSearchOptions &HSOpts) {
   llvm::Triple::OSType os = triple.getOS();
   // FIXME: temporary hack: hard-coded paths.
 
@@ -333,29 +332,31 @@
     default: break;
 
     case llvm::Triple::ppc:
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "powerpc-apple-darwin10");
+      break;
     case llvm::Triple::ppc64:
-      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
-                                  "powerpc-apple-darwin10", "", "ppc64",
-                                  triple);
-      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
-                                  "powerpc-apple-darwin10", "", "ppc64",
-                                  triple);
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "powerpc-apple-darwin10/ppc64");
       break;
-
     case llvm::Triple::x86:
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "i686-apple-darwin10");
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "i686-apple-darwin8");
+      break;
     case llvm::Triple::x86_64:
-      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
-                                  "i686-apple-darwin10", "", "x86_64", triple);
-      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
-                                  "i686-apple-darwin8", "", "", triple);
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "i686-apple-darwin10/x86_64");
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "i686-apple-darwin8/x86_64");
       break;
-
     case llvm::Triple::arm:
     case llvm::Triple::thumb:
-      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
-                                  "arm-apple-darwin10", "v7", "", triple);
-      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
-                                  "arm-apple-darwin10", "v6", "", triple);
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "arm-apple-darwin10/v7");
+      AddVersionedCPlusPlusIncludePaths("/usr/include/c++", "", 
+                                        "arm-apple-darwin10/v6");
       break;
     }
     return;
@@ -367,64 +368,48 @@
     llvm_unreachable("Include management is handled in the driver.");
 
   case llvm::Triple::Cygwin:
-    // Cygwin-1.7
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3");
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
-    // g++-4 / Cygwin-1.5
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
+    AddVersionedCPlusPlusIncludePaths("/usr/lib/gcc/i686-pc-cygwin", 
+                                      "/include/c++", "i686-pc-cygwin");
     break;
-  case llvm::Triple::MinGW32:
-    // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32)
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.0");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.1");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.2");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.3");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.4");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.0");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.2");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.3");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0");
-    // mingw.org C++ include paths
-    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.2");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.1");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.2");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
+  case llvm::Triple::MinGW32: {
+      // mingw-w64 C++ include paths
+      StringRef Base = HSOpts.ResourceDir + "/../../../include/c++";
+      AddVersionedCPlusPlusIncludePaths(Base, "", "/i686-w64-mingw32");
+      AddVersionedCPlusPlusIncludePaths(Base, "", "/x86_64-w64-mingw32");
+      // mingw.org C++ include paths
+      AddVersionedCPlusPlusIncludePaths("/mingw/lib/gcc/mingw32", 
+                                        "/include/c++", "mingw32"); // MSYS
+      AddVersionedCPlusPlusIncludePaths("c:/mingw/lib/gcc/mingw32", 
+                                        "/include/c++", "mingw32");
+    }
     break;
   case llvm::Triple::DragonFly:
     AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false);
     break;
   case llvm::Triple::FreeBSD:
-    // FreeBSD 8.0
-    // FreeBSD 7.3
-    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);
+    // Versions 7.3 and 8.0
+    AddVersionedCPlusPlusIncludePaths("/usr/include/c++/", "", "");
     break;
   case llvm::Triple::NetBSD:
-    AddGnuCPlusPlusIncludePaths("/usr/include/g++", "", "", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/g++", "");
     break;
   case llvm::Triple::OpenBSD: {
     std::string t = triple.getTriple();
     if (t.substr(0, 6) == "x86_64")
       t.replace(0, 6, "amd64");
-    AddGnuCPlusPlusIncludePaths("/usr/include/g++",
-                                t, "", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/g++", t);
     break;
   }
   case llvm::Triple::Minix:
-    AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
-                                "", "", "", triple);
+    AddVersionedCPlusPlusIncludePaths("/usr/gnu/include/c++", "", "");
     break;
   case llvm::Triple::Solaris:
-    AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/",
-                                "i386-pc-solaris2.11", "", "", triple);
+    AddVersionedCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++", 
+                                      "", "i386-pc-solaris2.11");
     // Solaris - Fall though..
   case llvm::Triple::AuroraUX:
-    // AuroraUX
-    AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4",
-                                "i386-pc-solaris2.11", "", "", triple);
+    AddVersionedCPlusPlusIncludePaths("/opt/gcc4/include/c++", 
+                                      "", "i386-pc-solaris2.11");
     break;
   default:
     break;


More information about the cfe-dev mailing list