From d6cecde585b0980ed8e0050c5a1d315789fb6356 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Sat, 17 Jun 2017 01:05:52 +0100 Subject: [PATCH] Remove the Windows GCC driver. Summary: This patch drops the GCC driver and instead moves the only remaining path that we need to keep for backwards compatibility to the settings file. It also generalizes the code that expands `$TopDir` so it can expand it within any location in the string and also changes it so `$TopDir` is expanded only after the words call because `$TopDir` can contains spaces which would be horribly broken. Test Plan: ./validate Reviewers: austin, hvr, bgamari Reviewed By: bgamari Subscribers: rwbarton, thomie, erikd GHC Trac Issues: #13709 Differential Revision: https://phabricator.haskell.org/D3592 --- aclocal.m4 | 3 +- compiler/main/SysTools.hs | 38 +++++++++++------- configure.ac | 8 ---- docs/users_guide/8.4.1-notes.rst | 3 ++ driver/gcc/gcc.c | 66 -------------------------------- 5 files changed, 30 insertions(+), 88 deletions(-) delete mode 100644 driver/gcc/gcc.c diff --git a/aclocal.m4 b/aclocal.m4 index db394f38d6..40aaf9167f 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -464,6 +464,7 @@ 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" @@ -486,6 +487,7 @@ AC_DEFUN([FP_SETTINGS], SettingsTouchCommand='$topdir/bin/touchy.exe' else SettingsCCompilerCommand="$CC" + SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2" SettingsHaskellCPPCommand="$HaskellCPPCmd" SettingsHaskellCPPFlags="$HaskellCPPArgs" SettingsLdCommand="$LdCmd" @@ -523,7 +525,6 @@ 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" diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs index 0a19feb2ce..f2878b0e7b 100644 --- a/compiler/main/SysTools.hs +++ b/compiler/main/SysTools.hs @@ -202,17 +202,10 @@ initSysTools mbMinusB Nothing -> pgmError ("Can't parse " ++ show platformConstantsFile) - 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) + 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 getBooleanSetting key = case lookup key mySettings of Just "YES" -> return True Just "NO" -> return False @@ -239,7 +232,11 @@ 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" - gcc_args_str <- getSetting "C compiler flags" + -- 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" gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie" cpp_prog <- getSetting "Haskell CPP command" cpp_args_str <- getSetting "Haskell CPP flags" @@ -252,7 +249,7 @@ initSysTools mbMinusB = ["-DTABLES_NEXT_TO_CODE"] | otherwise = [] cpp_args= map Option (words cpp_args_str) - gcc_args = map Option (words gcc_args_str + gcc_args = map (Option . resolveTopDir top_dir) (words gcc_args_str ++ unreg_gcc_args ++ tntc_gcc_args) ldSupportsCompactUnwind <- getBooleanSetting "ld supports compact unwind" @@ -363,6 +360,21 @@ 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) diff --git a/configure.ac b/configure.ac index 721f0e7b8b..d7c6ad83f4 100644 --- a/configure.ac +++ b/configure.ac @@ -302,8 +302,6 @@ 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" @@ -366,12 +364,6 @@ 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 } diff --git a/docs/users_guide/8.4.1-notes.rst b/docs/users_guide/8.4.1-notes.rst index f23cb360c9..14aab5db3b 100644 --- a/docs/users_guide/8.4.1-notes.rst +++ b/docs/users_guide/8.4.1-notes.rst @@ -80,6 +80,9 @@ 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 `_ for a complete list. diff --git a/driver/gcc/gcc.c b/driver/gcc/gcc.c deleted file mode 100644 index b398c5ea46..0000000000 --- a/driver/gcc/gcc.c +++ /dev/null @@ -1,66 +0,0 @@ - -/* 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 -#include - -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); -} - -- GitLab