diff options
-rw-r--r-- | compiler/GHC/Driver/Pipeline/Execute.hs | 5 | ||||
-rw-r--r-- | configure.ac | 143 | ||||
-rw-r--r-- | driver/gcc/gcc.c | 66 | ||||
-rw-r--r-- | m4/fp_settings.m4 | 145 | ||||
-rw-r--r-- | m4/fp_setup_windows_toolchain.m4 | 107 | ||||
-rw-r--r-- | mk/config.mk.in | 12 | ||||
-rwxr-xr-x | mk/get-win32-tarballs.py | 2 |
7 files changed, 212 insertions, 268 deletions
diff --git a/compiler/GHC/Driver/Pipeline/Execute.hs b/compiler/GHC/Driver/Pipeline/Execute.hs index 61fc86c836..da214cdc20 100644 --- a/compiler/GHC/Driver/Pipeline/Execute.hs +++ b/compiler/GHC/Driver/Pipeline/Execute.hs @@ -1089,12 +1089,15 @@ enabled in the toolchain: suggests, this tells the linker to produce a bigobj-enabled COFF object, no a PE executable. -We must enable bigobj output in a few places: +Previously when we used ld.bfd we had to enable bigobj output in a few places: * When merging object files (GHC.Driver.Pipeline.Execute.joinObjectFiles) * When assembling (GHC.Driver.Pipeline.runPhase (RealPhase As ...)) +However, this is no longer necessary with ld.lld, which detects that the +object is large on its own. + Unfortunately the big object format is not supported on 32-bit targets so none of this can be used in that case. diff --git a/configure.ac b/configure.ac index 95d0043f59..7f2fb42bc6 100644 --- a/configure.ac +++ b/configure.ac @@ -354,111 +354,10 @@ AC_SUBST(TargetHasRTSLinker) # Requires FPTOOLS_SET_PLATFORMS_VARS to be run first. FP_FIND_ROOT - -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" - tarball_dest_dir="mingw-w64/i686" - tarball_mingw_dir="mingw32" - else - mingw_arch="x86_64" - tarball_dest_dir="mingw-w64/x86_64" - tarball_mingw_dir="mingw64" - fi -fi - -set_up_tarballs() { - AC_MSG_NOTICE([Checking for Windows toolchain tarballs...]) - local action - if test "$TarballsAutodownload" = "NO" - then - action="verify" - else - action="download" - fi - $PYTHON mk/get-win32-tarballs.py $action $mingw_arch > missing-win32-tarballs - case $? in - 0) - rm missing-win32-tarballs - ;; - 2) - echo - echo "Error:" - echo "Needed msys2 tarballs are missing. You have a few options to get them," - echo - echo " * run configure with the --enable-tarballs-autodownload option" - echo - echo " * run mk/get-win32-tarballs.py download $mingw_arch" - echo - echo " * manually download the files listed in ./missing-win32-tarballs and place" - echo " them in the ghc-tarballs directory." - echo - exit 1 - ;; - *) - echo - echo "Error fetching msys2 tarballs; see errors above." - exit 1 - ;; - esac - - # Extract all the tarballs in one go - if ! test -d inplace/mingw - then - AC_MSG_NOTICE([Extracting Windows toolchain from archives (may take a while)...]) - rm -rf inplace/mingw - local base_dir="../ghc-tarballs/${tarball_dest_dir}" - ( cd inplace && - find "${base_dir}" -name "*.tar.xz" -exec tar --xz -xf {} \; && - find "${base_dir}" -name "*.tar.zst" -exec tar --zstd -xf {} \; && - rm ".MTREE" && - rm ".PKGINFO" && - cd .. ) || AC_MSG_ERROR([Could not extract Windows toolchains.]) - - 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 -} - -# See Note [tooldir: How GHC finds mingw on Windows] -if test "$HostOS" = "mingw32" -a "$EnableDistroToolchain" = "NO" -then - test -d inplace || mkdir inplace - - # NB. Download and extract the MingW-w64 distribution if required - set_up_tarballs - - mingwbin="$hardtop/inplace/mingw/bin/" - CC="${mingwbin}gcc.exe" - LD="${mingwbin}ld.exe" - NM="${mingwbin}nm.exe" - RANLIB="${mingwbin}ranlib.exe" - OBJDUMP="${mingwbin}objdump.exe" - MergeObjsCmd="$LD" - MergeObjsArgs="-r --oformat=pe-bigobj-x86-64" - fp_prog_ar="${mingwbin}ar.exe" - - AC_PATH_PROG([Genlib],[genlib]) -fi - -# We don't want to bundle a MinGW-w64 toolchain -# So we have to find these individual tools. -# See Note [tooldir: How GHC finds mingw on Windows] -if test "$EnableDistroToolchain" = "YES" -then +# Extract and configure the Windows toolchain +if test "$HostOS" = "mingw32" -a "$EnableDistroToolchain" = "NO"; then + FP_SETUP_WINDOWS_TOOLCHAIN +else # Ideally should use AC_CHECK_TARGET_TOOL but our triples # are screwed up. Configure doesn't think they're ever equal and # so never tried without the prefix. @@ -471,28 +370,28 @@ then AC_PATH_PROG([DllWrap],[dllwrap]) AC_PATH_PROG([Windres],[windres]) AC_PATH_PROG([Genlib],[genlib]) -else - AC_CHECK_TARGET_TOOL([Windres],[windres]) - AC_CHECK_TARGET_TOOL([DllWrap],[dllwrap]) - AC_CHECK_TARGET_TOOL([OBJDUMP],[objdump]) -fi -DllWrapCmd="$DllWrap" -WindresCmd="$Windres" + HAVE_GENLIB=False + if test "$HostOS" = "mingw32"; then + AC_CHECK_TARGET_TOOL([Windres],[windres]) + AC_CHECK_TARGET_TOOL([DllWrap],[dllwrap]) + AC_CHECK_TARGET_TOOL([OBJDUMP],[objdump]) -HAVE_GENLIB=False -if test "$HostOS" = "mingw32" -then - if test "$Genlib" != ""; then - GenlibCmd="$(cygpath -m $Genlib)" - HAVE_GENLIB=True + if test "$Genlib" != ""; then + GenlibCmd="$(cygpath -m $Genlib)" + HAVE_GENLIB=True + fi fi fi -AC_SUBST([DllWrapCmd]) -AC_SUBST([WindresCmd]) -AC_SUBST([GenlibCmd]) -AC_SUBST([HAVE_GENLIB]) +if test "$HostOS" = "mingw32"; then + DllWrapCmd="$DllWrap" + WindresCmd="$Windres" + AC_SUBST([DllWrapCmd]) + AC_SUBST([WindresCmd]) + AC_SUBST([GenlibCmd]) + AC_SUBST([HAVE_GENLIB]) +fi FP_ICONV FP_GMP diff --git a/driver/gcc/gcc.c b/driver/gcc/gcc.c deleted file mode 100644 index aa63bb0498..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 <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, NULL); -} - diff --git a/m4/fp_settings.m4 b/m4/fp_settings.m4 index 09a24f33e1..4db7cd46af 100644 --- a/m4/fp_settings.m4 +++ b/m4/fp_settings.m4 @@ -1,104 +1,113 @@ # FP_SETTINGS # ---------------------------------- # Set the variables used in the settings file -# See Note [tooldir: How GHC finds mingw on Windows] AC_DEFUN([FP_SETTINGS], [ - if test "$windows" = YES -a "$EnableDistroToolchain" = "NO" - then + SettingsUseDistroMINGW="$EnableDistroToolchain" + + if test "$windows" = YES -a "$EnableDistroToolchain" = "NO"; then + # Handle the Windows toolchain installed in FP_SETUP_WINDOWS_TOOLCHAIN. + # See Note [tooldir: How GHC finds mingw on Windows] mingw_bin_prefix='$$tooldir/mingw/bin/' - SettingsCCompilerCommand="${mingw_bin_prefix}gcc.exe" - SettingsHaskellCPPCommand="${mingw_bin_prefix}gcc.exe" - SettingsHaskellCPPFlags="$HaskellCPPArgs" - SettingsLdCommand="${mingw_bin_prefix}ld.exe" - # Overrides FIND_MERGE_OBJECTS in order to avoid hard-coding linker - # path on Windows (#18550). - SettingsMergeObjectsCommand="${SettingsLdCommand}" - SettingsMergeObjectsFlags="-r --oformat=pe-bigobj-x86-64" - SettingsArCommand="${mingw_bin_prefix}ar.exe" - SettingsRanlibCommand="${mingw_bin_prefix}ranlib.exe" - SettingsDllWrapCommand="${mingw_bin_prefix}dllwrap.exe" - SettingsWindresCommand="${mingw_bin_prefix}windres.exe" - SettingsTouchCommand='$$topdir/bin/touchy.exe' - elif test "$EnableDistroToolchain" = "YES" - then - SettingsCCompilerCommand="$(basename $CC)" + SettingsCCompilerCommand="${mingw_bin_prefix}clang.exe" SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2" SettingsCxxCompilerFlags="$CONF_CXX_OPTS_STAGE2" - SettingsHaskellCPPCommand="$(basename $HaskellCPPCmd)" + SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" + SettingsHaskellCPPCommand="${mingw_bin_prefix}clang.exe" SettingsHaskellCPPFlags="$HaskellCPPArgs" - SettingsLdCommand="$(basename $LdCmd)" - SettingsMergeObjectsCommand="$(basename $MergeObjsCmd)" - SettingsMergeObjectsFlags="$MergeObjsArgs" - SettingsArCommand="$(basename $ArCmd)" - SettingsDllWrapCommand="$(basename $DllWrapCmd)" - SettingsWindresCommand="$(basename $WindresCmd)" + SettingsLdCommand="${mingw_bin_prefix}ld.lld.exe" + SettingsLdFlags="" + # LLD does not support object merging (#21068) + SettingsMergeObjectsCommand="" + SettingsMergeObjectsFlags="" + SettingsArCommand="${mingw_bin_prefix}llvm-ar.exe" + SettingsRanlibCommand="${mingw_bin_prefix}llvm-ranlib.exe" + SettingsDllWrapCommand="${mingw_bin_prefix}llvm-dllwrap.exe" + SettingsWindresCommand="${mingw_bin_prefix}llvm-windres.exe" SettingsTouchCommand='$$topdir/bin/touchy.exe' + else + # This case handles the "normal" platforms (e.g. not Windows) where we + # don't provide the toolchain. + SettingsCCompilerCommand="$CC" + SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2" + SettingsCxxCompilerFlags="$CONF_CXX_OPTS_STAGE2" SettingsHaskellCPPCommand="$HaskellCPPCmd" SettingsHaskellCPPFlags="$HaskellCPPArgs" + SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" SettingsLdCommand="$LdCmd" - SettingsMergeObjectsCommand="$MergeObjsCmd" - SettingsMergeObjectsFlags="$MergeObjsArgs" + SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2" SettingsArCommand="$ArCmd" SettingsRanlibCommand="$RanlibCmd" - if test -z "$DllWrapCmd" - then + SettingsMergeObjectsCommand="$MergeObjsCmd" + SettingsMergeObjectsFlags="$MergeObjsArgs" + + if test -z "$DllWrapCmd"; then SettingsDllWrapCommand="/bin/false" else SettingsDllWrapCommand="$DllWrapCmd" fi - if test -z "$WindresCmd" - then + if test -z "$WindresCmd"; then SettingsWindresCommand="/bin/false" else SettingsWindresCommand="$WindresCmd" fi - SettingsTouchCommand='touch' + + if test "$HostOS" = "mingw32"; then + SettingsTouchCommand='$$topdir/bin/touchy.exe' + else + SettingsTouchCommand='touch' + fi + + if test "$EnableDistroToolchain" = "YES"; then + # If the user specified --enable-distro-toolchain then we just use the + # executable names, not paths. + SettingsCCompilerCommand="$(basename $SettingsCCompilerCommand)" + SettingsHaskellCPPCommand="$(basename $SettingsHaskellCPPCommand)" + SettingsLdCommand="$(basename $SettingsLdCommand)" + SettingsMergeObjectsCommand="$(basename $SettingsMergeObjectsCommand)" + SettingsArCommand="$(basename $SettingsArCommand)" + SettingsDllWrapCommand="$(basename $SettingsDllWrapCommand)" + SettingsWindresCommand="$(basename $SettingsWindresCommand)" + fi fi - if test -z "$LibtoolCmd" - then - SettingsLibtoolCommand="libtool" - else - SettingsLibtoolCommand="$LibtoolCmd" + + # Platform-agnostic tools + if test -z "$LibtoolCmd"; then + LibtoolCmd="libtool" fi - if test -z "$ClangCmd" - then - SettingsClangCommand="clang" - else - SettingsClangCommand="$ClangCmd" + SettingsLibtoolCommand="$LibtoolCmd" + + if test -z "$ClangCmd"; then + ClangCmd="clang" fi - if test -z "$LlcCmd" - then - SettingsLlcCommand="llc" - else - SettingsLlcCommand="$LlcCmd" + SettingsClangCommand="$ClangCmd" + + # LLVM backend tools + if test -z "$LlcCmd"; then + LlcCmd="llc" fi - if test -z "$OptCmd" - then - SettingsOptCommand="opt" - else - SettingsOptCommand="$OptCmd" + SettingsLlcCommand="$LlcCmd" + + if test -z "$OptCmd"; then + OptCmd="opt" fi - if test -z "$OtoolCmd" - then - SettingsOtoolCommand="otool" - else - SettingsOtoolCommand="$OtoolCmd" + SettingsOptCommand="$OptCmd" + + # Mac-only tools + if test -z "$OtoolCmd"; then + OtoolCmd="otool" fi - if test -z "$InstallNameToolCmd" - then - SettingsInstallNameToolCommand="install_name_tool" - else - SettingsInstallNameToolCommand="$InstallNameToolCmd" + SettingsOtoolCommand="$OtoolCmd" + + if test -z "$InstallNameToolCmd"; then + InstallNameToolCmd="install_name_tool" fi - SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2" - SettingsCxxCompilerFlags="$CONF_CXX_OPTS_STAGE2" - SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" + SettingsInstallNameToolCommand="$InstallNameToolCmd" + SettingsCCompilerSupportsNoPie="$CONF_GCC_SUPPORTS_NO_PIE" - SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2" - SettingsUseDistroMINGW="$EnableDistroToolchain" + AC_SUBST(SettingsCCompilerCommand) AC_SUBST(SettingsHaskellCPPCommand) AC_SUBST(SettingsHaskellCPPFlags) diff --git a/m4/fp_setup_windows_toolchain.m4 b/m4/fp_setup_windows_toolchain.m4 new file mode 100644 index 0000000000..35e322c8a0 --- /dev/null +++ b/m4/fp_setup_windows_toolchain.m4 @@ -0,0 +1,107 @@ +AC_DEFUN([FP_SETUP_WINDOWS_TOOLCHAIN],[ + # Find the mingw-w64 archive file to extract. + if test "$HostArch" = "i386" + then + mingw_arch="i686" + tarball_dest_dir="mingw-w64/i686" + tarball_mingw_dir="clang32" + else + mingw_arch="x86_64" + tarball_dest_dir="mingw-w64/x86_64" + tarball_mingw_dir="clang64" + fi + + set_up_tarballs() { + AC_MSG_NOTICE([Checking for Windows toolchain tarballs...]) + local action + if test "$TarballsAutodownload" = "NO" + then + action="verify" + else + action="download" + fi + $PYTHON mk/get-win32-tarballs.py $action $mingw_arch > missing-win32-tarballs + case $? in + 0) + rm missing-win32-tarballs + ;; + 2) + echo + echo "Error:" + echo "Needed msys2 tarballs are missing. You have a few options to get them," + echo + echo " * run configure with the --enable-tarballs-autodownload option" + echo + echo " * run mk/get-win32-tarballs.py download $mingw_arch" + echo + echo " * manually download the files listed in ./missing-win32-tarballs and place" + echo " them in the ghc-tarballs directory." + echo + exit 1 + ;; + *) + echo + echo "Error fetching msys2 tarballs; see errors above." + exit 1 + ;; + esac + + # Extract all the tarballs in one go + if ! test -d inplace/mingw + then + AC_MSG_NOTICE([Extracting Windows toolchain from archives (may take a while)...]) + rm -rf inplace/mingw + local base_dir="../ghc-tarballs/${tarball_dest_dir}" + ( cd inplace && + find "${base_dir}" -name "*.tar.xz" -exec tar --xz -xf {} \; && + find "${base_dir}" -name "*.tar.zst" -exec tar --zstd -xf {} \; && + rm ".MTREE" && + rm ".PKGINFO" && + cd .. ) || AC_MSG_ERROR([Could not extract Windows toolchains.]) + + mv "inplace/${tarball_mingw_dir}" inplace/mingw && + touch inplace/mingw + AC_MSG_NOTICE([In-tree MingW-w64 tree created]) + fi + } + + # See Note [tooldir: How GHC finds mingw on Windows] + test -d inplace || mkdir inplace + + # NB. Download and extract the MingW-w64 distribution if required + set_up_tarballs + + # N.B. The parameters which get plopped in the `settings` file used by the + # resulting compiler are computed in `FP_SETTINGS`. + + # Our Windows toolchain is based around Clang and LLD. We use compiler-rt + # for the runtime, libc++ and libc++abi for the C++ standard library + # implementation, and libunwind for C++ unwinding. + mingwbin="$hardtop/inplace/mingw/bin/" + + CC="${mingwbin}clang.exe" + cflags="--rtlib=compiler-rt" + CFLAGS="$cflags" + CONF_CC_OPTS_STAGE1="$cflags" + CONF_CC_OPTS_STAGE2="$cflags" + + cxxflags="--rtlib=compiler-rt --unwindlib=libunwind --stdlib=libc++" + CXXFLAGS="$cxxflags" + CONF_CXX_OPTS_STAGE1="$cxxflags" + CONF_CXX_OPTS_STAGE2="$cxxflags" + + CONF_GCC_LINKER_OPTS_STAGE1="-fuse-ld=lld $cflags" + CONF_GCC_LINKER_OPTS_STAGE2="-fuse-ld=lld $cflags" + + LD="${mingwbin}ld.lld.exe" + NM="${mingwbin}llvm-nm.exe" + AR="${mingwbin}llvm-ar.exe" + RANLIB="${mingwbin}llvm-ranlib.exe" + OBJDUMP="${mingwbin}llvm-objdump.exe" + DLLTOOL="${mingwbin}llvm-dlltool.exe" + + # N.B. LLD does not support -r + MergeObjsCmd="" + MergeObjsArgs="" + AC_PATH_PROG([Genlib],[genlib]) +]) diff --git a/mk/config.mk.in b/mk/config.mk.in index 06e1dabd96..e1474a34a3 100644 --- a/mk/config.mk.in +++ b/mk/config.mk.in @@ -655,11 +655,7 @@ SRC_HSC2HS_OPTS_STAGE0 += --cflag=-D$(HostArch_CPP)_HOST_ARCH --cflag=-D$(HostOS SRC_HSC2HS_OPTS_STAGE1 += --cflag=-D$(TargetArch_CPP)_HOST_ARCH --cflag=-D$(TargetOS_CPP)_HOST_OS SRC_HSC2HS_OPTS_STAGE2 += --cflag=-D$(TargetArch_CPP)_HOST_ARCH --cflag=-D$(TargetOS_CPP)_HOST_OS -ifeq "$(TARGETPLATFORM)" "i386-unknown-mingw32" -WINDRES = $(INPLACE_MINGW)/bin/windres -else ifeq "$(TARGETPLATFORM)" "x86_64-unknown-mingw32" -WINDRES = $(INPLACE_MINGW)/bin/windres -endif +WINDRES=@WindresCmd@ #----------------------------------------------------------------------------- # Python for testsuite driver and code generators @@ -670,11 +666,7 @@ PYTHON=@PythonCmd@ # Mingwex Library # HaveLibMingwEx = @HaveLibMingwEx@ -ifeq "$(TARGETPLATFORM)" "i386-unknown-mingw32" -DLLTOOL = inplace/mingw/bin/dlltool.exe -else ifeq "$(TARGETPLATFORM)" "x86_64-unknown-mingw32" -DLLTOOL = inplace/mingw/bin/dlltool.exe -endif +DLLTOOL = @DlltoolCmd@ #----------------------------------------------------------------------------- # Other standard (ha!) Unix utilities diff --git a/mk/get-win32-tarballs.py b/mk/get-win32-tarballs.py index f1ada96b48..351212ba71 100755 --- a/mk/get-win32-tarballs.py +++ b/mk/get-win32-tarballs.py @@ -8,7 +8,7 @@ import argparse import sys from sys import stderr -TARBALL_VERSION = '0.3' +TARBALL_VERSION = '0.7' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] |