[cfe-commits] Possible contribution

Amer Agovic agov0001 at umn.edu
Thu Oct 28 10:10:16 PDT 2010


Hi Clang Team,
   I came across your project recently and found it very interesting. 
Downloaded 2.8 and compiled it on Win32 using MinGW32 (TDM 4.5.0) 
sitting in a non-standard location (c:/projects/bin/mingw).
Compile worked nicely and LLVM and CLANG work. However simple clang++ -v 
tt.cpp shows that my CPATH env var is not added (for c or c++) and the 
search dirs it uses are based on MinGW being in c:/mingw. After closer 
inspection I have notice that for many targets hard coded paths are used 
and I might have a better solution. If you agree please consider these 
suggestions.

I would like to submit following code for possible consideration. If you 
find it useful (and I think it is) please show me how to commit or one 
of you can commit.

Please consider making following changes:
In file InitHeaderSearch.cpp

Change existing method: AddDefaultCIncludePaths
To this:

case llvm::Triple::MinGW64:
   case llvm::Triple::MinGW32:
     {
       std::string base=GetMinGWBase();
     AddPath(base+"/include", System, true, false, false);
     }
     break;

Change existing method:AddDefaultCPlusPlusIncludePaths(
to this:
case llvm::Triple::MinGW32:
     {
     std::string base=GetMinGWBase();
    // Try gcc 4.5.0
     AddMinGWCPlusPlusIncludePaths(base+"/lib/gcc", "mingw32", "4.5.0");
     // Try gcc 4.4.0
     AddMinGWCPlusPlusIncludePaths(base+"/lib/gcc", "mingw32", "4.4.0");
     // Try gcc 4.3.0
     AddMinGWCPlusPlusIncludePaths(base+"/lib/gcc", "mingw32", "4.3.0");
     }
     break;

Add following two methods in the same file:


  /** Finds full path that contains provided substring within a 
collection of paths.
  * You can supply any Env var that holds path collections and extract 
paths from it
  * that match a partial string. The path returned is only up to the 
part so even if a path
  * is mentioned that is used for BIN folder you get the actual base path.
  * Search is case insensitive and should work for Win and Unix paths. 
If Mac and other
  * platforms fail then what we consider path and name separators needs 
to be generalized.
  * Finds the first occurance of provided parial string.
  * Path separators used: :;"'
  * Name separators used: /\
  * @param body string with collection of paths
  * @param part partial string known to be present in our desired path base
  * @return path base from last path separator until the first path 
separator after part
  */
std::string FindPathBase(const std::string &body,const std::string &part){
     // convert to lower case for case insesitive search
     std::string lbody=body;
     std::transform(lbody.begin(), lbody.end(), lbody.begin(),
                (int(*)(int)) std::tolower);
     std::string lpart=part;
     std::transform(lpart.begin(), lpart.end(), lpart.begin(),
                (int(*)(int)) std::tolower);

     std::string ret="";
     // locate first occurance
     int plen=lpart.length();
     int blen=lbody.length();
     int state=-1; // when it reaches plen we got a match
     int index=0;
     for(;index<blen && state<(plen-1);index++){
         char cl=lbody[index];
         char cr=lpart[state+1];
         if(cl=='\\') cl='/'; //translate name separator
         if(cr=='\\') cr='/';
         if(cl==cr){
             state++; // advance fsm state
         }else{
             state=-1;// reset fsm state
         }
     }
     if(state!=(plen-1)) return ret; // no luck
     // index points to first occurance
     // now we find teh start and end of the path
     int end=index;
     int begin=end-plen;
     // look for end
     while(end<blen){
         char c=lbody[end];
         // we try to sense a path or name delimiter and break there
         if(c=='/' || c=='\\' || c==':' || c==';' || c=='"' || c=='\'') 
break;
         end++;
     }
     // look for begin
     while(begin>0){
         char c=lbody[begin-1];
         // we try to sense a path separator
         if((c==':' && lbody[begin]!='\\')  || c==';' || c=='"' || 
c=='\'') break;
         begin--;
     }
     // should have being and end with blen that contains part
     ret=body.substr(begin,end-begin);
     return ret;
}

   /// Returns the base or root folder of MinGW
   std::string GetMinGWBase(){
           const char * path=getenv("PATH");
           return FindPathBase(path,"/mingw");
   }




More information about the cfe-commits mailing list