
Serge S. Gulin pushed to branch wip/T25974 at Glasgow Haskell Compiler / GHC Commits: 4631de44 by Serge S. Gulin at 2025-05-06T11:26:23+03:00 Add Wine support - - - - - 8 changed files: - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - boot - configure.ac - hadrian/src/Builder.hs - hadrian/src/Rules/BinaryDist.hs - libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc - m4/find_merge_objects.m4 Changes: ===================================== .gitlab/ci.sh ===================================== @@ -75,6 +75,15 @@ Environment variables affecting both build systems: NIX_SYSTEM On Darwin, the target platform of the desired toolchain (either "x86-64-darwin" or "aarch-darwin") NO_BOOT Whether to run ./boot or not, used when testing the source dist + TOOLCHAIN_SOURCE Select a source of toolchain. Possible values: + - "env": Toolchains are included in the Docker image via environment + variables. Default for Linux. + - "nix": Toolchains are provided via .gitlab/darwin/toolchain.nix. + Default for Darwin. + - "extracted": + Toolchains will be downloaded and extracted through the + CI process. Default for other systems. Windows and FreeBSD + are included. Environment variables determining build configuration of Hadrian system: @@ -83,14 +92,14 @@ Environment variables determining build configuration of Hadrian system: This tests the "reinstall" configuration CROSS_EMULATOR The emulator to use for testing of cross-compilers. -Environment variables determining bootstrap toolchain (Linux): +Environment variables determining bootstrap toolchain (TOOLCHAIN_SOURCE=env): GHC Path of GHC executable to use for bootstrapping. CABAL Path of cabal-install executable to use for bootstrapping. ALEX Path of alex executable to use for bootstrapping. HAPPY Path of alex executable to use for bootstrapping. -Environment variables determining bootstrap toolchain (non-Linux): +Environment variables determining bootstrap toolchain (TOOLCHAIN_SOURCE=extracted): GHC_VERSION Which GHC version to fetch for bootstrapping. CABAL_INSTALL_VERSION @@ -132,10 +141,33 @@ function setup_locale() { } function mingw_init() { + if [[ "${TOOLCHAIN_SOURCE:-}" =~ "env" ]]; then + # We assume that passed GHC will be used as a bootstrap ghc compiler + if [ -n "${GHC:-}" ]; then + boot_triple=$($GHC --info | awk -F'"' '/Target platform/ {print $4}') + else + boot_triple=$(ghc --info | awk -F'"' '/Target platform/ {print $4}') + fi + else + case "$MSYSTEM" in + CLANG64) + boot_triple="x86_64-unknown-mingw32" # triple of bootstrap GHC + ;; + CLANGARM64) + boot_triple="aarch64-unknown-mingw32" # triple of bootstrap GHC + ;; + *) + fail "win32-init: Unknown MSYSTEM $MSYSTEM" + ;; + esac + fi + case "$MSYSTEM" in CLANG64) target_triple="x86_64-unknown-mingw32" - boot_triple="x86_64-unknown-mingw32" # triple of bootstrap GHC + ;; + CLANGARM64) + target_triple="aarch64-unknown-mingw32" ;; *) fail "win32-init: Unknown MSYSTEM $MSYSTEM" @@ -150,10 +182,19 @@ function mingw_init() { MINGW_MOUNT_POINT="${MINGW_PREFIX}" PATH="$MINGW_MOUNT_POINT/bin:$PATH" - # We always use mingw64 Python to avoid path length issues like #17483. - export PYTHON="/mingw64/bin/python3" - # And need to use sphinx-build from the environment - export SPHINXBUILD="/mingw64/bin/sphinx-build.exe" + case "$MSYSTEM" in + CLANGARM64) + # At MSYS for ARM64 we force to use their special versions to speedup the compiler step + export PYTHON="/clangarm64/bin/python3" + export SPHINXBUILD="/clangarm64/bin/sphinx-build.exe" + ;; + *) + # We always use mingw64 Python to avoid path length issues like #17483. + export PYTHON="/mingw64/bin/python3" + # And need to use sphinx-build from the environment + export SPHINXBUILD="/mingw64/bin/sphinx-build.exe" + ;; + esac } # This will contain GHC's local native toolchain @@ -178,15 +219,21 @@ function show_tool() { } function set_toolchain_paths() { - case "$(uname -m)-$(uname)" in - # Linux toolchains are included in the Docker image - *-Linux) toolchain_source="env" ;; - # Darwin toolchains are provided via .gitlab/darwin/toolchain.nix - *-Darwin) toolchain_source="nix" ;; - *) toolchain_source="extracted" ;; - esac + if [ -z "${TOOLCHAIN_SOURCE:-}" ] + then + # Fallback to automatic detection which could not work for cases + # when cross compiler will be build at Windows environment + # and requires a special mingw compiler (not bundled) + case "$(uname -m)-$(uname)" in + # Linux toolchains are included in the Docker image + *-Linux) TOOLCHAIN_SOURCE="env" ;; + # Darwin toolchains are provided via .gitlab/darwin/toolchain.nix + *-Darwin) TOOLCHAIN_SOURCE="nix" ;; + *) TOOLCHAIN_SOURCE="extracted" ;; + esac + fi - case "$toolchain_source" in + case "$TOOLCHAIN_SOURCE" in extracted) # These are populated by setup_toolchain GHC="$toolchain/bin/ghc$exe" @@ -217,7 +264,7 @@ function set_toolchain_paths() { : ${HAPPY:=$(which happy)} : ${ALEX:=$(which alex)} ;; - *) fail "bad toolchain_source" + *) fail "bad TOOLCHAIN_SOURCE" esac export GHC @@ -247,7 +294,7 @@ function setup() { cp -Rf "$CABAL_CACHE"/* "$CABAL_DIR" fi - case $toolchain_source in + case $TOOLCHAIN_SOURCE in extracted) time_it "setup" setup_toolchain ;; *) ;; esac @@ -405,6 +452,17 @@ function configure() { if [[ -n "${target_triple:-}" ]]; then args+=("--target=$target_triple") fi + if [[ "${TOOLCHAIN_SOURCE:-}" =~ "extracted" ]]; then + # To extract something need download something first. + args+=("--enable-tarballs-autodownload") + else + # For Windows we should explicitly --enable-distro-toolchain + # if i.e. we decided to use TOOLCHAIN_SOURCE = env + case "$(uname)" in + MSYS_*|MINGW*) args+=("--enable-distro-toolchain") ;; + *) ;; + esac + fi if [[ -n "${ENABLE_NUMA:-}" ]]; then args+=("--enable-numa") else @@ -421,7 +479,6 @@ function configure() { # See https://stackoverflow.com/questions/7577052 for a rationale for the # args[@] symbol-soup below. run ${CONFIGURE_WRAPPER:-} ./configure \ - --enable-tarballs-autodownload \ "${args[@]+"${args[@]}"}" \ GHC="$GHC" \ || ( cat config.log; fail "configure failed" ) @@ -562,12 +619,14 @@ function install_bindist() { read -r -a args <<< "${INSTALL_CONFIGURE_ARGS:-}" if [[ "${CROSS_TARGET:-no_cross_target}" =~ "mingw" ]]; then - # We suppose that host target = build target. + # We assume that BUILD=HOST. # By the fact above it is clearly turning out which host value is # for currently built compiler. # The fix for #21970 will probably remove this if-branch. - local -r CROSS_HOST_GUESS=$($SHELL ./config.guess) - args+=( "--target=$CROSS_TARGET" "--host=$CROSS_HOST_GUESS" ) + # Cut is needed due of See Note [Wide Triple Windows]. + # By default it guesses "(x86_64|aarch64)-w64-mingw32" + local -r CROSS_HOST_ARCH_GUESS=$($SHELL ./config.guess | cut -d'-' -f1) + args+=( "--target=$CROSS_TARGET" "--host=$CROSS_HOST_ARCH_GUESS-unknown-mingw32" ) # FIXME: The bindist configure script shouldn't need to be reminded of # the target platform. See #21970. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -1302,11 +1302,14 @@ cross_jobs = [ . setVariable "WindresCmd" (llvm_prefix ++ "windres") . setVariable "LLVMAS" (llvm_prefix ++ "clang") . setVariable "LD" (llvm_prefix ++ "ld") + -- See Note [Empty MergeObjsCmd] -- Windows target require to make linker merge feature check disabled. . setVariable "MergeObjsCmd" "" + -- Note [Wide Triple Windows] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- LLVM MinGW Linux Toolchain expects to recieve "aarch64-w64-mingw32" -- as a triple but we use more common "aarch64-unknown-mingw32". - -- Due of this we need configure ld manually for clang beacause + -- Due of this we need configure ld manually for clang because -- it will use system's ld otherwise when --target will be specified to -- unexpected triple. . setVariable "CFLAGS" cflags ===================================== boot ===================================== @@ -52,6 +52,8 @@ def autoreconf(): # Run autoreconf on everything that needs it. processes = {} if os.name == 'nt': + # Note [ACLOCAL_PATH for Windows] + # ~~~~~~~~~~~~~~~~~~~~~~~~~ # Get the normalized ACLOCAL_PATH for Windows # This is necessary since on Windows this will be a Windows # path, which autoreconf doesn't know doesn't know how to handle. ===================================== configure.ac ===================================== @@ -658,12 +658,13 @@ GHC_LLVM_TARGET_SET_VAR AC_SUBST(LlvmTarget) dnl ** See whether cc supports --target=<triple> and set -dnl CONF_CC_OPTS_STAGE[012] accordingly. -FP_CC_SUPPORTS_TARGET([$CC_STAGE0], [CONF_CC_OPTS_STAGE0], [CONF_CXX_OPTS_STAGE0]) +dnl CONF_CC_OPTS_STAGE[12] accordingly. FP_CC_SUPPORTS_TARGET([$CC], [CONF_CC_OPTS_STAGE1], [CONF_CXX_OPTS_STAGE1]) FP_CC_SUPPORTS_TARGET([$CC], [CONF_CC_OPTS_STAGE2], [CONF_CXX_OPTS_STAGE2]) -FP_PROG_CC_LINKER_TARGET([$CC_STAGE0], [CONF_CC_OPTS_STAGE0], [CONF_GCC_LINKER_OPTS_STAGE0]) +# CONF_CC_OPTS_STAGE0 should be left as is because it is already configured +# by bootstrap compiler settings + FP_PROG_CC_LINKER_TARGET([$CC], [CONF_CC_OPTS_STAGE1], [CONF_GCC_LINKER_OPTS_STAGE1]) FP_PROG_CC_LINKER_TARGET([$CC], [CONF_CC_OPTS_STAGE2], [CONF_GCC_LINKER_OPTS_STAGE2]) ===================================== hadrian/src/Builder.hs ===================================== @@ -26,7 +26,7 @@ import Hadrian.Builder.Tar import Hadrian.Oracles.Path import Hadrian.Oracles.TextFile import Hadrian.Utilities -import Oracles.Setting (bashPath, targetStage) +import Oracles.Setting (bashPath, targetStage, isWinHost) import System.Exit import System.IO (stderr) @@ -327,8 +327,14 @@ instance H.Builder Builder where Ar Unpack _ -> cmd' [Cwd output] [path] buildArgs buildOptions Autoreconf dir -> do + isWin <- isWinHost + let aclocal_env = + -- It is generally assumed that you would use MinGW's compilers from within an MSYS shell. + -- See Note [ACLOCAL_PATH for Windows] + if isWin then [AddEnv "ACLOCAL_PATH" "/c/msys64/usr/share/aclocal/"] + else [] bash <- bashPath - cmd' [Cwd dir] [bash, path] buildArgs buildOptions + cmd' (Cwd dir `cons` aclocal_env) [bash, path] buildArgs buildOptions Configure dir -> do -- Inject /bin/bash into `libtool`, instead of /bin/sh, ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -115,7 +115,12 @@ installTo relocatable prefix = do targetPlatform <- setting TargetPlatformFull let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty - runBuilder (Configure bindistFilesDir) ["--prefix="++prefix] [] [] + win <- isWinTarget + -- See Note [Empty MergeObjsCmd] + let disabledMerge = + if win then ["MergeObjsCmd="] + else [] + runBuilder (Configure bindistFilesDir) (["--prefix="++prefix] ++ disabledMerge) [] [] let env = case relocatable of Relocatable -> [AddEnv "RelocatableBuild" "YES"] NotRelocatable -> [] @@ -232,7 +237,7 @@ bindistRules = do -- N.B. the ghc-pkg executable may be prefixed with a target triple -- (c.f. #20267). ghcPkgName <- programName (vanillaContext Stage1 ghcPkg) - cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache"] + cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName <.> exe) ["recache"] ===================================== libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc ===================================== @@ -861,7 +861,9 @@ expirationTime mgr us = do -- The 'TimeoutCallback' will not be called more than once. -- -- Be careful not to exceed @maxBound :: Int@, which on 32-bit machines is only --- 2147483647 μs, less than 36 minutes. +-- 2147483647 microseconds, less than 36 minutes. +-- We can not use here utf/greek symbol due of: +-- _build/stage1/libraries/ghc-internal/build/GHC/Internal/Event/Windows.hs: commitBuffer: invalid argument (cannot encode character '\206') -- {-# NOINLINE registerTimeout #-} registerTimeout :: Manager -> Int -> TimeoutCallback -> IO TimeoutKey @@ -878,7 +880,9 @@ registerTimeout mgr@Manager{..} uSrelTime cb = do -- This has no effect if the timeout has already fired. -- -- Be careful not to exceed @maxBound :: Int@, which on 32-bit machines is only --- 2147483647 μs, less than 36 minutes. +-- 2147483647 microseconds, less than 36 minutes. +-- We can not use here utf/greek symbol due of: +-- _build/stage1/libraries/ghc-internal/build/GHC/Internal/Event/Windows.hs: commitBuffer: invalid argument (cannot encode character '\206') -- updateTimeout :: Manager -> TimeoutKey -> Seconds -> IO () updateTimeout mgr (TK key) relTime = do @@ -980,7 +984,7 @@ step maxDelay mgr@Manager{..} = do -- There are some unusual edge cases you need to deal with. The -- GetQueuedCompletionStatus function blocks a thread until there's -- work for it to do. Based on the return value, the number of bytes - -- and the overlapped structure, there’s a lot of possible "reasons" + -- and the overlapped structure, there's a lot of possible "reasons" -- for the function to have returned. Deciphering all the possible -- cases: -- ===================================== m4/find_merge_objects.m4 ===================================== @@ -33,6 +33,8 @@ AC_DEFUN([FIND_MERGE_OBJECTS],[ fi + # Note [Empty MergeObjsCmd] + # ~~~~~~~~~~~~~~~~~~~~~~~~~ # If MergeObjsCmd="" then we assume that the user is explicitly telling us that # they do not want to configure the MergeObjsCmd, this is particularly important for # the bundled windows toolchain. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4631de44afcc6e9ee839623a61c10519... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4631de44afcc6e9ee839623a61c10519... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Serge S. Gulin (@gulin.serge)