[cfe-dev] Fix sysrooted MinGW header search paths

Ruben Van Boxem vanboxem.ruben at gmail.com
Wed Jun 22 12:40:59 PDT 2011


2011/6/18 Ruben Van Boxem <vanboxem.ruben at gmail.com>:
> Attached is a patch to search directories relative to the cland
> executable location. This enables the common sysrooted MinGW to be
> used effectively.
>
> I needed to add a HeaderSearchOptions paramater to
> AddDefaultCPlusPlusIncludePaths, just like AddDefaultCIncludePaths
> already had. I used the ResourceDir Path variable to generate a
> correct relative path. I added all current versions of
> x86_64-w64-mingw32 C++ include paths, and corrected the mingw-w64 crt
> header path.
>
> This is half-hacky, but on top of all the hackery already present,
> this seems like an OK solution for now.
>
> This is what I propose in the long/"short future":
>
> 1. Change the HeaderSearchOptions ResourceDir variable to something
> more generally useful, like SysrootDir or something, and change the
> present use of that variable accordingly.
> 2. Enable some form of sysroot via configure/cmake that enables only
> these special directories to be searched. If not enabled, default to
> old behavior. This would place most of InitHeaderSearch.cpp in #ifdef
> LLVM_SYSROOT which is a good thing: less non-existing directories are
> used.
> 3. (long future) move the sysroot variable to some abstracter
> structure, to enable clang to also find system libraries once it can
> replace the system linker.
>
> Why is this necessary? The current form of --with-cxx-include-*
> configury does not allow relocation, which is very common and
> important on Windows. There is no "root filesystem".
>
> I can easily add the MinGW.org directories as well, but as the note in
> the file already mentions, there needs to be a way to find
> i686-w64-mingw32 (in the configure/cmake process), because its headers
> are located elsewhere. If there is a good way to convert a triple into
> a string, all of mingw-w64 (maybe even mingw.org) can be summarised in
> a couple of lines, without much if/switch work.
>
> Thanks!
>
> Ruben
>

Attached is an updated patch which adds support for the
i686-w64-mingw32 paths as well. This patch modifies
AddMinGW64CXXIncludePaths to work more like the non-*64* variant. This
expects CLang to be installed in the exact same place as a sysrooted
mingw-w64 GCC.

Comments or commits are welcome!

Ruben
-------------- next part --------------
Index: lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- lib/Frontend/InitHeaderSearch.cpp	(revision 133549)
+++ lib/Frontend/InitHeaderSearch.cpp	(working copy)
@@ -78,7 +78,8 @@
 
   /// AddMinGW64CXXPaths - Add the necessary paths to support
   /// libstdc++ of x86_64-w64-mingw32 aka mingw-w64.
-  void AddMinGW64CXXPaths(llvm::StringRef Base);
+  void AddMinGW64CXXPaths(llvm::StringRef Base,
+                          llvm::StringRef Version);
 
   /// AddDelimitedPaths - Add a list of paths delimited by the system PATH
   /// separator. The processing follows that of the CPATH variable for gcc.
@@ -90,7 +91,8 @@
 
   // AddDefaultCPlusPlusIncludePaths -  Add paths that should be searched when
   //  compiling c++.
-  void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple);
+  void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple,
+                                       const HeaderSearchOptions &HSOpts);
 
   /// AddDefaultSystemIncludePaths - Adds the default system include paths so
   ///  that e.g. stdio.h is found.
@@ -216,13 +218,17 @@
           CXXSystem, true, false, false);
 }
 
-void InitHeaderSearch::AddMinGW64CXXPaths(llvm::StringRef Base) {
-  AddPath(Base,
+void InitHeaderSearch::AddMinGW64CXXPaths(llvm::StringRef Base,
+                                          llvm::StringRef Version) {
+  // Assumes Base is HeaderSearchOpts' ResourceDir
+  AddPath(Base + "/../../../include/c++/" + Version,
           CXXSystem, true, false, false);
-  AddPath(Base + "/x86_64-w64-mingw32",
+  AddPath(Base + "/../../../include/c++/" + Version + "/x86_64-w64-mingw32",
           CXXSystem, true, false, false);
-  AddPath(Base + "/backward",
+  AddPath(Base + "/../../../include/c++/" + Version + "/i686-w64-mingw32",
           CXXSystem, true, false, false);
+  AddPath(Base + "/../../../include/c++/" + Version + "/backward",
+          CXXSystem, true, false, false);
 }
 
   // FIXME: This probably should goto to some platform utils place.
@@ -550,13 +556,21 @@
   case llvm::Triple::Cygwin:
     AddPath("/usr/include/w32api", System, true, false, false);
     break;
-  case llvm::Triple::MinGW32:
-    // FIXME: We should be aware of i686-w64-mingw32.
-    if (triple.getArch() == llvm::Triple::x86_64)
-      AddPath("c:/mingw/x86_64-w64-mingw32/include",
-              System, true, false, false);
+  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
+    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
+    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);
+    AddPath("c:/mingw/include", System, true, false, false); 
+    } // brace to work around error skipping P initialization when jumping
     break;
   case llvm::Triple::Linux:
     // Generic Debian multiarch support:
@@ -579,7 +593,7 @@
 }
 
 void InitHeaderSearch::
-AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) {
+AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) {
   llvm::Triple::OSType os = triple.getOS();
   llvm::StringRef CxxIncludeRoot(CXX_INCLUDE_ROOT);
   if (CxxIncludeRoot != "") {
@@ -639,20 +653,17 @@
     AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "3.4.4");
     break;
   case llvm::Triple::MinGW32:
-    // FIXME: We should be aware of i686-w64-mingw32.
-    if (triple.getArch() == llvm::Triple::x86_64) {
-      // mingw-w64-20110207
-      AddMinGW64CXXPaths("c:/mingw/x86_64-w64-mingw32/include/c++/4.5.3");
-      // mingw-w64-20101129
-      AddMinGW64CXXPaths("c:/mingw/x86_64-w64-mingw32/include/c++/4.5.2");
-    }
-    // Try gcc 4.5.2 (MSYS)
-    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2");
-    // Try gcc 4.5.0
+    // 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.6.0");
+    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1");
+    // mingw.org C++ include paths
+    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS
     AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0");
-    // Try gcc 4.4.0
     AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
-    // Try gcc 4.3.0
     AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
     break;
   case llvm::Triple::DragonFly:
@@ -924,7 +935,7 @@
     if (HSOpts.UseLibcxx)
       AddPath("/usr/include/c++/v1", CXXSystem, true, false, false);
     else
-      AddDefaultCPlusPlusIncludePaths(triple);
+      AddDefaultCPlusPlusIncludePaths(triple, HSOpts);
   }
 
   AddDefaultCIncludePaths(triple, HSOpts);


More information about the cfe-dev mailing list