Revert "Remove the Windows GCC driver."
authorSimon Peyton Jones <simonpj@microsoft.com>
Thu, 29 Jun 2017 14:34:39 +0000 (15:34 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Thu, 29 Jun 2017 14:34:39 +0000 (15:34 +0100)
This reverts commit d6cecde585b0980ed8e0050c5a1d315789fb6356.

The patch broke Simon PJ's Windows build, becuase he didn't
have (and should not need) a separate msys2 gcc.

Following an exchange on the ghc-devs list, Tamar wrote

  Oops, sorry, didn’t notice it because both mine and harbormaster’s
  msys2 have separate GCCs installed as well.

  I don’t see an easy fix that would also work for end user Configure
  based cabal installs. So I think I’ll have to go back to the drawing
  board for this one.

  You can just leave it reverted.

aclocal.m4
compiler/main/SysTools.hs
configure.ac
docs/users_guide/8.4.1-notes.rst
driver/gcc/gcc.c [new file with mode: 0644]

index 40aaf91..db394f3 100644 (file)
@@ -464,7 +464,6 @@ AC_DEFUN([FP_SETTINGS],
     then
         mingw_bin_prefix=mingw/bin/
         SettingsCCompilerCommand="\$topdir/../${mingw_bin_prefix}gcc.exe"
-        SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2 -B\$topdir/../mingw/bin/ -B\$topdir/../mingw/lib/"
         SettingsHaskellCPPCommand="\$topdir/../${mingw_bin_prefix}gcc.exe"
         SettingsHaskellCPPFlags="$HaskellCPPArgs"
         SettingsLdCommand="\$topdir/../${mingw_bin_prefix}ld.exe"
@@ -487,7 +486,6 @@ AC_DEFUN([FP_SETTINGS],
         SettingsTouchCommand='$topdir/bin/touchy.exe'
     else
         SettingsCCompilerCommand="$CC"
-        SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2"
         SettingsHaskellCPPCommand="$HaskellCPPCmd"
         SettingsHaskellCPPFlags="$HaskellCPPArgs"
         SettingsLdCommand="$LdCmd"
@@ -525,6 +523,7 @@ AC_DEFUN([FP_SETTINGS],
     else
       SettingsOptCommand="$OptCmd"
     fi
+    SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2"
     SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2"
     SettingsCCompilerSupportsNoPie="$CONF_GCC_SUPPORTS_NO_PIE"
     SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2"
index f2878b0..0a19feb 100644 (file)
@@ -202,10 +202,17 @@ initSysTools mbMinusB
                             Nothing ->
                                 pgmError ("Can't parse " ++
                                           show platformConstantsFile)
-       let getSettingRaw key = case lookup key mySettings of
-                                 Just xs -> return xs
-                                 Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
-           getSetting key = resolveTopDir top_dir <$> getSettingRaw key
+       let getSetting key = case lookup key mySettings of
+                            Just xs ->
+                                return $ case stripPrefix "$topdir" xs of
+                                         Just [] ->
+                                             top_dir
+                                         Just xs'@(c:_)
+                                          | isPathSeparator c ->
+                                             top_dir ++ xs'
+                                         _ ->
+                                             xs
+                            Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
            getBooleanSetting key = case lookup key mySettings of
                                    Just "YES" -> return True
                                    Just "NO" -> return False
@@ -232,11 +239,7 @@ initSysTools mbMinusB
        -- with the settings file, but it would be a little fiddly
        -- to make that possible, so for now you can't.
        gcc_prog <- getSetting "C compiler command"
-       -- TopDir can expand to something that contains spaces
-       -- for the argument string we apply words to the string in order to
-       -- break it up. So defer the expansion of $TopDir till after the words
-       -- call here.
-       gcc_args_str <- getSettingRaw "C compiler flags"
+       gcc_args_str <- getSetting "C compiler flags"
        gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie"
        cpp_prog <- getSetting "Haskell CPP command"
        cpp_args_str <- getSetting "Haskell CPP flags"
@@ -249,7 +252,7 @@ initSysTools mbMinusB
                = ["-DTABLES_NEXT_TO_CODE"]
             | otherwise = []
            cpp_args= map Option (words cpp_args_str)
-           gcc_args = map (Option . resolveTopDir top_dir) (words gcc_args_str
+           gcc_args = map Option (words gcc_args_str
                                ++ unreg_gcc_args
                                ++ tntc_gcc_args)
        ldSupportsCompactUnwind <- getBooleanSetting "ld supports compact unwind"
@@ -360,21 +363,6 @@ initSysTools mbMinusB
                     sPlatformConstants = platformConstants
              }
 
--- | This function will replace any usage of $TopDir in the given string
---   regardless of it's location within the string.
-resolveTopDir :: String -- ^ The value of $TopDir
-              -> String -- ^ The string to perform substitutions in
-              -> String -- ^ The resulting string with all subs done.
-resolveTopDir top_dir str
-  = case break (=='$') str of
-      (_, []) -> str
-      (x, xs) -> let rst = case stripPrefix "$topdir" xs of
-                             Just [] -> top_dir
-                             Just xs'@(c:_) | isPathSeparator c
-                                     -> top_dir ++ xs'
-                             _       -> xs
-                 in x ++ resolveTopDir top_dir rst
-
 -- returns a Unix-format path (relying on getBaseDir to do so too)
 findTopDir :: Maybe String -- Maybe TopDir path (without the '-B' prefix).
            -> IO String    -- TopDir (in Unix format '/' separated)
index 3c5e17a..c0961cf 100644 (file)
@@ -302,6 +302,8 @@ fail() {
 if test "$HostOS" = "mingw32"
 then
     # Find the mingw-w64 7z file to extract.
+    # NB. If you update the tarballs to a new version of gcc, don't
+    # forget to tweak the paths in driver/gcc/gcc.c.
     if test "$HostArch" = "i386"
     then
         mingw_arch="i686"
@@ -364,6 +366,12 @@ set_up_tarballs() {
         mv "inplace/${tarball_mingw_dir}" inplace/mingw &&
         touch inplace/mingw
 
+        # NB. Now since the GCC is hardcoded to use /mingw32 we need to
+        # make a wrapper around it to give it the proper paths
+        mv inplace/mingw/bin/gcc.exe inplace/mingw/bin/realgcc.exe
+        PATH=`pwd`/inplace/mingw/bin:$PATH
+        inplace/mingw/bin/realgcc.exe driver/gcc/gcc.c driver/utils/cwrapper.c driver/utils/getLocation.c -Idriver/utils -o inplace/mingw/bin/gcc.exe
+
         AC_MSG_NOTICE([In-tree MingW-w64 tree created])
     fi
 }
index 14aab5d..f23cb36 100644 (file)
@@ -80,9 +80,6 @@ Now we generate ::
   used to build a GHC using compilers on your ``PATH`` instead of using the
   bundled bindist. See :ghc-ticket:`13792`
 
-- Windows no longer uses an intermediate GCC driver and instead calls GCC
-  directly. See :ghc-ticket:`13709`.
-
 - Lots of other bugs. See `Trac <https://ghc.haskell.org/trac/ghc/query?status=closed&milestone=8.4.1&col=id&col=summary&col=status&col=type&col=priority&col=milestone&col=component&order=priority>`_
   for a complete list.
 
diff --git a/driver/gcc/gcc.c b/driver/gcc/gcc.c
new file mode 100644 (file)
index 0000000..b398c5e
--- /dev/null
@@ -0,0 +1,66 @@
+
+/* gcc on mingw is hardcoded to use /mingw (which is c:/mingw) to
+   find various files. If this is a different version of mingw to the
+   one that we have in the GHC tree then things can go wrong. We
+   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 <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char** argv) {
+    char *binDir;
+    char *exePath;
+    char *preArgv[4];
+    char *oldPath;
+    char *newPath;
+    char *base;
+    char *version;
+    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");
+    }
+
+    /* GCC Version. */
+    version = mkString("%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
+
+    /* 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);
+#if defined(__MINGW64__)
+    base = mkString("x86_64-w64-mingw32");
+#else
+    base = mkString("i686-w64-mingw32");
+#endif
+
+    preArgv[2] = mkString("-B%s/../lib/gcc/%s/%s"    , binDir, base, version);
+    preArgv[3] = mkString("-B%s/../libexec/gcc/%s/%s", binDir, base, version);
+
+    run(exePath, 4, preArgv, argc - 1, argv + 1);
+}
+