[cfe-dev] Version agnostic path search for mingw

Nikola Smiljanic popizdeh at gmail.com
Sun Mar 18 02:52:32 PDT 2012


Here's something we talked about on IRC, it should have two effects:

1. regex is used to match directories of the form x.x.x, this should
be the only change for mingw-w64
2. clang doesn't add all the necessary paths when it comes to
mingw.org, it only includes c:/mingw/include (hello world will fail to
compile due to missing stddef.h). I added
c:\MinGW\lib\gcc\mingw32\x.x.x\include and
c:\MinGW\lib\gcc\mingw32\x.x.x\include-fixed directories. The order in
which they are added is the same one that mingw.org uses (got this
from gcc -xc -E -v -), this is why the call to
AddPath("c:/mingw/include") is inside the loop even though it doesn't
depend on any loop variable.

I have no idea how this plays with MSYS and Cygwin, but it shouldn't
change the logic, I'm only adding more paths. The code doesn't follow
the 80 column width convention, this is something I'll change before
submitting the patch to cfe-commits, it's just easier to read this
way.
-------------- next part --------------
Index: lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- lib/Frontend/InitHeaderSearch.cpp	(revision 152997)
+++ 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
 
@@ -64,17 +66,17 @@
                                    StringRef Dir32,
                                    StringRef Dir64,
                                    const llvm::Triple &triple);
+  
+  /// AddMinGWCIncludePaths - Add MinGW paths that should always be searched
+  void AddMinGWCIncludePaths(StringRef Base);
 
   /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
   ///  libstdc++.
-  void AddMinGWCPlusPlusIncludePaths(StringRef Base,
-                                     StringRef Arch,
-                                     StringRef Version);
+  void AddMinGWCPlusPlusIncludePaths(StringRef Base, StringRef Arch);
 
   /// AddMinGW64CXXPaths - Add the necessary paths to support
   /// libstdc++ of x86_64-w64-mingw32 aka mingw-w64.
-  void AddMinGW64CXXPaths(StringRef Base,
-                          StringRef Version);
+  void AddMinGW64CXXPaths(StringRef Base);
 
   // AddDefaultCIncludePaths - Add paths that should always be searched.
   void AddDefaultCIncludePaths(const llvm::Triple &triple,
@@ -178,28 +180,53 @@
   AddPath(Base + "/backward", CXXSystem, true, false, false);
 }
 
+void InitHeaderSearch::AddMinGWCIncludePaths(StringRef Base)
+{
+  llvm::error_code EC;
+  // match directories of the form x.x.x
+  llvm::Regex Regex("[0-9]\\.[[0-9]\\.[0-9]$");
+  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::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);
+                                                     StringRef Arch) {
+  llvm::error_code EC;
+  // match directories of the form x.x.x
+  llvm::Regex Regex("[0-9]\\.[[0-9]\\.[0-9]$");
+  for (llvm::sys::fs::directory_iterator Dir(Base + "/" + Arch, 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/c++", CXXSystem, true, false, false);
+      AddPath(Dir->path() + "/include/c++/" + Arch, CXXSystem, true, false, false);
+      AddPath(Dir->path() + "/include/c++/backward", CXXSystem, true, false, false);
+    }
+  }
 }
 
-void InitHeaderSearch::AddMinGW64CXXPaths(StringRef Base,
-                                          StringRef Version) {
+void InitHeaderSearch::AddMinGW64CXXPaths(StringRef Base) {
+  llvm::error_code EC;
+  // match directories of the form x.x.x
+  llvm::Regex Regex("[0-9]\\.[[0-9]\\.[0-9]$");
   // 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);
+  for (llvm::sys::fs::directory_iterator Dir(Base + "/../../../include/c++/", 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(), CXXSystem, true, false, false);
+      AddPath(Dir->path() + "/x86_64-w64-mingw32", CXXSystem, true, false, false);
+      AddPath(Dir->path() + "/i686-w64-mingw32", CXXSystem, true, false, false);
+      AddPath(Dir->path() + "/backward", CXXSystem, true, false, false);
+    }
+  }
 }
 
 void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
@@ -311,7 +338,7 @@
       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;
       
@@ -368,31 +395,17 @@
 
   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");
+    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin");
+    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin");
     // g++-4 / Cygwin-1.5
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
+    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "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");
+    AddMinGW64CXXPaths(HSOpts.ResourceDir);
     // 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");
+    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32"); //MSYS
+    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32");
     break;
   case llvm::Triple::DragonFly:
     AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false);


More information about the cfe-dev mailing list