Advertisement
missdeer

InitHeaderSearch.cpp.diff

Jul 23rd, 2012
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 8.18 KB | None | 0 0
  1. Index: InitHeaderSearch.cpp
  2. ===================================================================
  3. --- InitHeaderSearch.cpp    (revision 160614)
  4. +++ InitHeaderSearch.cpp    (working copy)
  5. @@ -28,6 +28,12 @@
  6.  
  7.  #include "clang/Config/config.h" // C_INCLUDE_DIRS
  8.  
  9. +#ifdef __MINGW32__
  10. +#include <iostream>
  11. +#include <fstream>
  12. +#include <Windows.h>
  13. +#endif
  14. +
  15.  using namespace clang;
  16.  using namespace clang::frontend;
  17.  
  18. @@ -46,6 +52,14 @@
  19.    std::string IncludeSysroot;
  20.    bool IsNotEmptyOrRoot;
  21.  
  22. +#ifdef __MINGW32__
  23. +  std::string mingwGCCPath;
  24. +  std::string mingwArch;
  25. +  std::string mingwGCCVersion;
  26. +  void ParseMinGWGCCInstallation(const char * gccPath);
  27. +  void DetectMinGWInstallation();
  28. +  bool PathFileExistsA(const char * pszPath);
  29. +#endif
  30.  public:
  31.  
  32.    InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot)
  33. @@ -101,6 +115,7 @@
  34.    /// Realize - Merges all search path lists into one list and send it to
  35.    /// HeaderSearch.
  36.    void Realize(const LangOptions &Lang);
  37. +  
  38.  };
  39.  
  40.  }  // end anonymous namespace.
  41. @@ -381,25 +396,11 @@
  42.      AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
  43.      break;
  44.    case llvm::Triple::MinGW32:
  45. +    DetectMinGWInstallation();
  46.      // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32)
  47. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.0");
  48. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.1");
  49. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.2");
  50. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.3");
  51. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.4");
  52. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.0");
  53. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1");
  54. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.2");
  55. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.3");
  56. -    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0");
  57. +   AddMinGW64CXXPaths(HSOpts.ResourceDir, mingwGCCVersion);
  58.      // mingw.org C++ include paths
  59. -    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS
  60. -    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.2");
  61. -    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.1");
  62. -    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.2");
  63. -    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0");
  64. -    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
  65. -    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
  66. +    AddMinGWCPlusPlusIncludePaths(mingwGCCPath + "/../lib/gcc", mingwArch, mingwGCCVersion);
  67.      break;
  68.    case llvm::Triple::DragonFly:
  69.      AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false);
  70. @@ -654,6 +655,191 @@
  71.    }
  72.  }
  73.  
  74. +#ifdef __MINGW32__
  75. +void InitHeaderSearch::ParseMinGWGCCInstallation(const char * gccPath)
  76. +{
  77. +    // get gcc target and version
  78. +    char szCmdLine[MAX_PATH] = {0};
  79. +    strcpy(szCmdLine, gccPath);
  80. +    strcat(szCmdLine, " -v");
  81. +
  82. +    HANDLE  hStdInRead;      
  83. +    HANDLE  hStdInWrite;    
  84. +    HANDLE  hStdOutRead;    
  85. +    HANDLE  hStdOutWrite;  
  86. +    HANDLE  hStdErrWrite;    
  87. +
  88. +    SECURITY_ATTRIBUTES sa ;
  89. +    sa.nLength = sizeof( SECURITY_ATTRIBUTES ) ;
  90. +    sa.lpSecurityDescriptor = NULL ;
  91. +    sa.bInheritHandle = TRUE ;  
  92. +
  93. +    if   (!CreatePipe(&hStdInRead, &hStdInWrite,&sa, 0))  
  94. +        return;  
  95. +
  96. +    if  (!CreatePipe(&hStdOutRead, &hStdOutWrite,&sa, 0))  
  97. +        return;  
  98. +
  99. +    if (!DuplicateHandle(GetCurrentProcess(), hStdOutWrite, GetCurrentProcess(), &hStdErrWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))  
  100. +        return;  
  101. +
  102. +    STARTUPINFOA si = {0};
  103. +    si.cb = sizeof(si);
  104. +    si.dwFlags  = STARTF_USESTDHANDLES;
  105. +    si.dwFlags |= STARTF_USESHOWWINDOW;
  106. +    si.hStdError = hStdErrWrite;
  107. +    si.hStdOutput = hStdOutWrite;
  108. +    si.hStdInput = hStdInRead;
  109. +    si.wShowWindow = SW_HIDE;
  110. +
  111. +    PROCESS_INFORMATION pi;
  112. +    char szWorkingDir[MAX_PATH] = {0};
  113. +    strcpy(szWorkingDir, gccPath);
  114. +    char *p = strrchr(szWorkingDir, '\\');
  115. +    p++;
  116. +    *p = 0;
  117. +    BOOL bSuccess =  CreateProcessA(NULL,
  118. +        szCmdLine,
  119. +        NULL,
  120. +        NULL,
  121. +        TRUE,
  122. +        0,
  123. +        NULL,
  124. +        szWorkingDir,
  125. +        &si,
  126. +        &pi
  127. +        );
  128. +    if (bSuccess)
  129. +    {
  130. +        DWORD bytesRead = 0 ;  
  131. +        std::string output;
  132. +        WaitForSingleObject(pi.hProcess, INFINITE);
  133. +        while ( true )  
  134. +        {
  135. +            char buffer[512] = { 0 } ;
  136. +            bSuccess = ReadFile( hStdOutRead , buffer , 512 , &bytesRead , NULL );
  137. +            output.append(buffer, bytesRead);
  138. +            if( bSuccess == FALSE || bytesRead < 512 )
  139. +                break;
  140. +        }
  141. +
  142. +        //  parse the output
  143. +        size_t targetPos = output.find("Target:", 0);
  144. +        if (targetPos != std::string::npos)
  145. +        {
  146. +            // extract the target info
  147. +            char * start =  const_cast<char*>(output.c_str());
  148. +            start = start + targetPos + strlen("Target:");
  149. +            while(!isalnum(*start))start++;
  150. +            char * end = start+1;
  151. +            while(*end != '\r' && *end != '\n')end++;
  152. +            mingwArch.append(start, end - start);
  153. +        }
  154. +        size_t versionPos = output.find("gcc version");
  155. +        if (versionPos != std::string::npos)
  156. +        {
  157. +            // extract the version info
  158. +            char * start = const_cast<char*>(output.c_str());
  159. +            start = start + versionPos + strlen("gcc version");
  160. +            while(!isalnum(*start))start++;
  161. +            char * end = start+1;
  162. +            while(*end != ' ')end++;
  163. +            mingwGCCVersion.append(start, end - start);
  164. +        }
  165. +
  166. +        // extract the path info
  167. +        const char *p = strrchr(gccPath , '\\');
  168. +        mingwGCCPath.append(gccPath, p - gccPath);
  169. +    }
  170. +    CloseHandle( hStdInRead ) ;
  171. +    CloseHandle(hStdInWrite);
  172. +    CloseHandle( hStdOutRead ) ;
  173. +    CloseHandle(hStdOutWrite);
  174. +    CloseHandle( hStdErrWrite ) ;
  175. +    CloseHandle(pi.hThread);
  176. +    CloseHandle(pi.hProcess);
  177. +
  178. +}
  179. +
  180. +void InitHeaderSearch::DetectMinGWInstallation()
  181. +{
  182. +    if (!(mingwArch.empty() && mingwGCCPath.empty() && mingwGCCVersion.empty()))
  183. +        return;
  184. +
  185. +    char szPath[MAX_PATH] = {0};
  186. +    // application directory
  187. +    GetModuleFileNameA(NULL, szPath, MAX_PATH);
  188. +    char* p = strrchr(szPath, '\\');
  189. +    p++;
  190. +    strcpy(p, "gcc.exe");
  191. +    if (PathFileExistsA(szPath))
  192. +    {
  193. +        ParseMinGWGCCInstallation(szPath);
  194. +        return;
  195. +    }
  196. +
  197. +    // in path environment
  198. +    char * pPath = getenv ("PATH");
  199. +    if (pPath)
  200. +    {
  201. +        size_t len = strlen(pPath);
  202. +        char * pszPathEnv = new char[len + 1];
  203. +        strcpy(pszPathEnv, pPath);
  204. +        // split by ;
  205. +        char * dirInPath = strtok( pszPathEnv, ";" );                
  206. +
  207. +        do
  208. +        {    
  209. +            strcpy(szPath, dirInPath);
  210. +            strcat(szPath, "\\gcc.exe");
  211. +
  212. +            if (PathFileExistsA(szPath))
  213. +            {
  214. +                ParseMinGWGCCInstallation(szPath);
  215. +                delete[] pszPathEnv;
  216. +                return;
  217. +            }
  218. +        }  while ((dirInPath = strtok( NULL, ";" )) != NULL);
  219. +
  220. +        delete[] pszPathEnv;
  221. +    }
  222. +
  223. +    // in Drives root path
  224. +    DWORD dwDrives = ::GetLogicalDrives();
  225. +    dwDrives >>= 2; // start from C drive
  226. +    for (char i = 0; i < 30; i++)
  227. +    {
  228. +        char A = 'C';
  229. +        if (dwDrives & 0x01)
  230. +        {
  231. +            A += i;
  232. +            szPath[0] = A;
  233. +            szPath[1] = 0;
  234. +            strcat(szPath, ":\\mingw\\bin\\gcc.exe");
  235. +
  236. +            if (PathFileExistsA(szPath))
  237. +            {
  238. +                ParseMinGWGCCInstallation(szPath);
  239. +                return;
  240. +            }
  241. +        }
  242. +        dwDrives >>= 1;
  243. +    }
  244. +}
  245. +bool InitHeaderSearch::PathFileExistsA(const char * pszPath)
  246. +{
  247. +    std::fstream _file;
  248. +    _file.open(pszPath,std::ios::in);
  249. +    if(!_file)
  250. +    {
  251. +        return false;
  252. +    }
  253. +
  254. +    _file.close();
  255. +    return true;
  256. +}
  257. +#endif
  258. +
  259.  void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
  260.                                       const HeaderSearchOptions &HSOpts,
  261.                                       const LangOptions &Lang,
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement