X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=driver%2Fgcc%2Fgcc.c;h=ea1f480b4d31d509a91edb2571c584188630275c;hp=c086f748e573b3d39d45e369b6247396ea37e730;hb=HEAD;hpb=80aea54a820cd718d47ff43b6988d2ea3ed615ae diff --git a/driver/gcc/gcc.c b/driver/gcc/gcc.c index c086f74..ea1f480 100644 --- a/driver/gcc/gcc.c +++ b/driver/gcc/gcc.c @@ -5,104 +5,51 @@ therefore need to add various -B flags to the gcc commandline, so that it uses our in-tree mingw. Hence this wrapper. */ +#include "cwrapper.h" #include "getLocation.h" -#include -#include + #include #include -#include -#include - -static void die(const char *fmt, ...) { - va_list argp; - - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); - exit(1); -} - -static char *mkString(const char *fmt, ...) { - char *p; - int i, j; - va_list argp; - - va_start(argp, fmt); - i = vsnprintf(NULL, 0, fmt, argp); - va_end(argp); - - if (i < 0) { - die("snprintf 0 failed: errno %d: %s\n", errno, strerror(errno)); - } - - p = malloc(i + 1); - if (p == NULL) { - die("malloc failed: errno %d: %s\n", errno, strerror(errno)); - } - - va_start(argp, fmt); - j = vsnprintf(p, i + 1, fmt, argp); - va_end(argp); - if (i < 0) { - die("snprintf with %d failed: errno %d: %s\n", - i + 1, errno, strerror(errno)); - } - - return p; -} - -char *quote(char *str) { - char *quotedStr; - char *p; - int i; - - quotedStr = malloc(2 * strlen(str) + 2 + 1); - if (quotedStr == NULL) { - die("malloc failed: errno %d: %s\n", errno, strerror(errno)); - } - p = quotedStr; - *p++ = '"'; - while (*str) { - if (*str == '"') { - *p++ = '\\'; - } - *p++ = *str++; - } - *p++ = '"'; - *p = '\0'; - - return quotedStr; -} int main(int argc, char** argv) { - char *p; char *binDir; char *exePath; - char *bArg; - char **newArgv; - int i, j, ret; + char *preArgv[4]; + char *oldPath; + char *newPath; + int n; binDir = getExecutablePath(); exePath = mkString("%s/realgcc.exe", binDir); + /* We need programs like + inplace/mingw/libexec/gcc/mingw32/4.5.0/cc1.exe + to be able to find the DLLs in inplace/mingw/bin, so we need to + add it to $PATH */ + oldPath = getenv("PATH"); + if (!oldPath) { + die("Couldn't read PATH\n"); + } + n = snprintf(NULL, 0, "PATH=%s;%s", binDir, oldPath); + n++; + newPath = malloc(n); + if (!newPath) { + die("Couldn't allocate space for PATH\n"); + } + snprintf(newPath, n, "PATH=%s;%s", binDir, oldPath); + n = putenv(newPath); + if (n) { + die("putenv failed\n"); + } + /* Without these -B args, gcc will still work. However, if you have a mingw installation in c:/mingw then it will use files from that in preference to the in-tree files. */ + preArgv[0] = mkString("-B%s", binDir); + preArgv[1] = mkString("-B%s/../lib", binDir); + preArgv[2] = mkString("-B%s/../lib/gcc/mingw32/4.5.2", binDir); + preArgv[3] = mkString("-B%s/../libexec/gcc/mingw32/4.5.2", binDir); - newArgv = malloc(sizeof(char *) * (argc + 4 + 1)); - newArgv[0] = quote(exePath); - newArgv[1] = quote(mkString("-B%s", binDir)); - newArgv[2] = quote(mkString("-B%s/../lib", binDir)); - newArgv[3] = quote(mkString("-B%s/../lib/gcc/mingw32/3.4.5", binDir)); - newArgv[4] = quote(mkString("-B%s/../libexec/gcc/mingw32/3.4.5", binDir)); - for (i = 1; i < argc; i++) { - newArgv[4 + i] = quote(argv[i]); - } - newArgv[4 + argc] = NULL; - // execv(exePath, argv); - ret = spawnv(_P_WAIT, exePath, (const char* const*)newArgv); - if (errno) { - die("spawnv failed: errno %d: %s\n", errno, strerror(errno)); - } - exit(ret); + run(exePath, 4, preArgv, argc - 1, argv + 1); } +