David Eichmann pushed to branch wip/dcoutts/windows-rts-dll at Glasgow Haskell Compiler / GHC
Commits:
-
68eff119
by Duncan Coutts at 2026-05-05T14:51:51+01:00
-
50192927
by Duncan Coutts at 2026-05-05T14:51:51+01:00
-
0ef6450c
by Duncan Coutts at 2026-05-05T14:51:51+01:00
-
95501811
by Duncan Coutts at 2026-05-05T14:51:51+01:00
-
fba86f1e
by Duncan Coutts at 2026-05-05T14:51:51+01:00
15 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- configure.ac
- distrib/configure.ac.in
- hadrian/cfg/default.host.target.in
- hadrian/cfg/default.target.in
- hadrian/src/Builder.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Library.hs
- hadrian/src/Rules/Rts.hs
- m4/fp_setup_windows_toolchain.m4
- m4/ghc_toolchain.m4
- m4/prep_target_file.m4
- rts/.gitignore
- + rts/win32/libHSghc-internal.def.in
Changes:
| ... | ... | @@ -1305,6 +1305,7 @@ cross_jobs = [ |
| 1305 | 1305 | . setVariable "STRINGS" (llvm_prefix ++ "strings")
|
| 1306 | 1306 | . setVariable "STRIP" (llvm_prefix ++ "strip")
|
| 1307 | 1307 | . setVariable "WindresCmd" (llvm_prefix ++ "windres")
|
| 1308 | + . setVariable "DlltoolCmd" (llvm_prefix ++ "llvm-dlltool")
|
|
| 1308 | 1309 | . setVariable "LLVMAS" (llvm_prefix ++ "clang")
|
| 1309 | 1310 | . setVariable "LD" (llvm_prefix ++ "ld")
|
| 1310 | 1311 | -- Windows target require to make linker merge feature check disabled.
|
| ... | ... | @@ -317,6 +317,7 @@ |
| 317 | 317 | "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
|
| 318 | 318 | "CROSS_TARGET": "aarch64-unknown-mingw32",
|
| 319 | 319 | "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
|
| 320 | + "DlltoolCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-dlltool",
|
|
| 320 | 321 | "HADRIAN_ARGS": "--docs=none",
|
| 321 | 322 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 322 | 323 | "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
|
| ... | ... | @@ -399,6 +400,7 @@ |
| 399 | 400 | "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
|
| 400 | 401 | "CROSS_TARGET": "aarch64-unknown-mingw32",
|
| 401 | 402 | "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
|
| 403 | + "DlltoolCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-dlltool",
|
|
| 402 | 404 | "HADRIAN_ARGS": "--docs=none",
|
| 403 | 405 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 404 | 406 | "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
|
| ... | ... | @@ -1111,6 +1113,7 @@ |
| 1111 | 1113 | "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
|
| 1112 | 1114 | "CROSS_TARGET": "aarch64-unknown-mingw32",
|
| 1113 | 1115 | "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
|
| 1116 | + "DlltoolCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-dlltool",
|
|
| 1114 | 1117 | "HADRIAN_ARGS": "--docs=none",
|
| 1115 | 1118 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 1116 | 1119 | "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
|
| ... | ... | @@ -1194,6 +1197,7 @@ |
| 1194 | 1197 | "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
|
| 1195 | 1198 | "CROSS_TARGET": "aarch64-unknown-mingw32",
|
| 1196 | 1199 | "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
|
| 1200 | + "DlltoolCmd": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-llvm-dlltool",
|
|
| 1197 | 1201 | "HADRIAN_ARGS": "--docs=none",
|
| 1198 | 1202 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 1199 | 1203 | "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
|
| ... | ... | @@ -314,13 +314,16 @@ else |
| 314 | 314 | AC_CHECK_TOOL([RANLIB],[ranlib])
|
| 315 | 315 | AC_CHECK_TOOL([OBJDUMP],[objdump])
|
| 316 | 316 | AC_CHECK_TOOL([WindresCmd],[windres])
|
| 317 | + AC_CHECK_TOOL([DlltoolCmd],[llvm-dlltool])
|
|
| 317 | 318 | AC_CHECK_TOOL([Genlib],[genlib])
|
| 318 | 319 | |
| 319 | 320 | if test "$HostOS" = "mingw32"; then
|
| 320 | 321 | AC_CHECK_TARGET_TOOL([WindresCmd],[windres])
|
| 322 | + AC_CHECK_TARGET_TOOL([DlltoolCmd],[llvm-dlltool])
|
|
| 321 | 323 | AC_CHECK_TARGET_TOOL([OBJDUMP],[objdump])
|
| 322 | 324 | |
| 323 | 325 | WindresCmd="$(cygpath -m $WindresCmd)"
|
| 326 | + DlltoolCmd="$(cygpath -m $DlltoolCmd)"
|
|
| 324 | 327 | |
| 325 | 328 | if test "$Genlib" != ""; then
|
| 326 | 329 | GenlibCmd="$(cygpath -m $Genlib)"
|
| ... | ... | @@ -1080,9 +1083,10 @@ echo "\ |
| 1080 | 1083 | libdw : $UseLibdw
|
| 1081 | 1084 | |
| 1082 | 1085 | Using LLVM tools
|
| 1083 | - llc : $LlcCmd
|
|
| 1084 | - opt : $OptCmd
|
|
| 1085 | - llvm-as : $LlvmAsCmd"
|
|
| 1086 | + llc : $LlcCmd
|
|
| 1087 | + opt : $OptCmd
|
|
| 1088 | + llvm-as : $LlvmAsCmd
|
|
| 1089 | + llvm-dlltool : $DlltoolCmd"
|
|
| 1086 | 1090 | |
| 1087 | 1091 | if test "$HSCOLOUR" = ""; then
|
| 1088 | 1092 | echo "
|
| ... | ... | @@ -229,6 +229,12 @@ FIND_LLVM_PROG([LLVMAS], [clang], [$LlvmMinVersion], [$LlvmMaxVersion]) |
| 229 | 229 | LlvmAsCmd="$LLVMAS"
|
| 230 | 230 | AC_SUBST([LlvmAsCmd])
|
| 231 | 231 | |
| 232 | +dnl ** Which LLVM llvm-dlltool to use?
|
|
| 233 | +dnl --------------------------------------------------------------
|
|
| 234 | +AC_ARG_VAR(DlltoolCmd,[Use as the path to LLVM's llvm-dlltool [default=autodetect]])
|
|
| 235 | +FIND_LLVM_PROG([DlltoolCmd], [llvm-dlltool], [$LlvmMinVersion], [$LlvmMaxVersion])
|
|
| 236 | +AC_SUBST([DlltoolCmd])
|
|
| 237 | + |
|
| 232 | 238 | dnl We know that `clang` supports `--target` and it is necessary to pass it
|
| 233 | 239 | dnl lest we see #25793.
|
| 234 | 240 | if test -z "$LlvmAsFlags" && ! test -z "$LlvmTarget"; then
|
| ... | ... | @@ -45,6 +45,7 @@ Target |
| 45 | 45 | , tgtOpt = Nothing
|
| 46 | 46 | , tgtLlvmAs = Nothing
|
| 47 | 47 | , tgtWindres = Nothing
|
| 48 | +, tgtDlltool = Nothing
|
|
| 48 | 49 | , tgtOtool = Nothing
|
| 49 | 50 | , tgtInstallNameTool = Nothing
|
| 50 | 51 | } |
| ... | ... | @@ -45,6 +45,7 @@ Target |
| 45 | 45 | , tgtOpt = @OptCmdMaybeProg@
|
| 46 | 46 | , tgtLlvmAs = @LlvmAsCmdMaybeProg@
|
| 47 | 47 | , tgtWindres = @WindresCmdMaybeProg@
|
| 48 | +, tgtDlltool = @DlltoolCmdMaybeProg@
|
|
| 48 | 49 | , tgtOtool = @OtoolCmdMaybeProg@
|
| 49 | 50 | , tgtInstallNameTool = @InstallNameToolCmdMaybeProg@
|
| 50 | 51 | } |
| ... | ... | @@ -17,7 +17,7 @@ import Development.Shake.Classes |
| 17 | 17 | import Development.Shake.Command
|
| 18 | 18 | import Development.Shake.FilePath
|
| 19 | 19 | import GHC.Generics
|
| 20 | -import GHC.Platform.ArchOS (ArchOS(..), Arch(..))
|
|
| 20 | +import GHC.Platform.ArchOS (ArchOS(..), Arch(..), OS(..))
|
|
| 21 | 21 | import qualified Hadrian.Builder as H
|
| 22 | 22 | import Hadrian.Builder hiding (Builder)
|
| 23 | 23 | import Hadrian.Builder.Ar
|
| ... | ... | @@ -180,6 +180,7 @@ data Builder = Alex |
| 180 | 180 | | Objdump
|
| 181 | 181 | | Python
|
| 182 | 182 | | Ranlib
|
| 183 | + | Dlltool
|
|
| 183 | 184 | | Testsuite TestMode
|
| 184 | 185 | | Sphinx SphinxMode
|
| 185 | 186 | | Tar TarMode
|
| ... | ... | @@ -418,6 +419,7 @@ isOptional target = \case |
| 418 | 419 | Alex -> True
|
| 419 | 420 | -- Most ar implemententions no longer need ranlib, but some still do
|
| 420 | 421 | Ranlib -> not $ Toolchain.arNeedsRanlib (tgtAr target)
|
| 422 | + Dlltool -> archOS_OS (tgtArchOs target) /= OSMinGW32
|
|
| 421 | 423 | JsCpp -> not $ (archOS_arch . tgtArchOs) target == ArchJavaScript -- ArchWasm32 too?
|
| 422 | 424 | _ -> False
|
| 423 | 425 | |
| ... | ... | @@ -442,6 +444,7 @@ systemBuilderPath builder = case builder of |
| 442 | 444 | Objdump -> fromKey "objdump"
|
| 443 | 445 | Python -> fromKey "python"
|
| 444 | 446 | Ranlib -> fromTargetTC "ranlib" (maybeProg Toolchain.ranlibProgram . tgtRanlib)
|
| 447 | + Dlltool -> fromTargetTC "dlltool" (maybeProg id . tgtDlltool)
|
|
| 445 | 448 | Testsuite _ -> fromKey "python"
|
| 446 | 449 | Sphinx _ -> fromKey "sphinx-build"
|
| 447 | 450 | Tar _ -> fromKey "tar"
|
| ... | ... | @@ -377,6 +377,7 @@ templateRules = do |
| 377 | 377 | , interpolateSetting "ProjectPatchLevel1" ProjectPatchLevel1
|
| 378 | 378 | , interpolateSetting "ProjectPatchLevel2" ProjectPatchLevel2
|
| 379 | 379 | ]
|
| 380 | + templateRule "rts/win32/libHSghc-internal.def" projectVersion
|
|
| 380 | 381 | templateRule "docs/index.html" $ packageUnitIds Stage1
|
| 381 | 382 | templateRule "docs/users_guide/ghc_config.py" $ mconcat
|
| 382 | 383 | [ projectVersion
|
| ... | ... | @@ -4,6 +4,8 @@ import Hadrian.BuildPath |
| 4 | 4 | import Hadrian.Haskell.Cabal
|
| 5 | 5 | import Hadrian.Haskell.Cabal.Type
|
| 6 | 6 | import qualified Text.Parsec as Parsec
|
| 7 | +import GHC.Platform.ArchOS (ArchOS(archOS_OS), OS(..))
|
|
| 8 | +import GHC.Toolchain.Target (Target(tgtArchOs))
|
|
| 7 | 9 | |
| 8 | 10 | import Base
|
| 9 | 11 | import Context
|
| ... | ... | @@ -185,9 +187,13 @@ jsObjects context = do |
| 185 | 187 | srcs <- interpretInContext context (getContextData jsSrcs)
|
| 186 | 188 | mapM (objectPath context) srcs
|
| 187 | 189 | |
| 188 | --- | Return extra object files needed to build the given library context. The
|
|
| 189 | --- resulting list is currently non-empty only when the package from the
|
|
| 190 | --- 'Context' is @ghc-internal@ built with in-tree GMP backend.
|
|
| 190 | +-- | Return extra object files needed to build the given library context.
|
|
| 191 | +--
|
|
| 192 | +-- This is non-empty for:
|
|
| 193 | +--
|
|
| 194 | +-- * @ghc-internal@ when built with in-tree GMP backend
|
|
| 195 | +-- * @rts@ on Windows when linking dynamically
|
|
| 196 | +--
|
|
| 191 | 197 | extraObjects :: Context -> Action [FilePath]
|
| 192 | 198 | extraObjects context
|
| 193 | 199 | | package context == ghcInternal = do
|
| ... | ... | @@ -195,6 +201,13 @@ extraObjects context |
| 195 | 201 | "gmp" -> gmpObjects (stage context)
|
| 196 | 202 | _ -> return []
|
| 197 | 203 | |
| 204 | + | package context == rts = do
|
|
| 205 | + target <- interpretInContext context getStagedTarget
|
|
| 206 | + builddir <- buildPath context
|
|
| 207 | + return [ builddir -/- "libHSghc-internal.dll.a"
|
|
| 208 | + | archOS_OS (tgtArchOs target) == OSMinGW32
|
|
| 209 | + , Dynamic `wayUnit` way context ]
|
|
| 210 | + |
|
| 198 | 211 | | otherwise = return []
|
| 199 | 212 | |
| 200 | 213 | -- | Return all the object files to be put into the library we're building for
|
| ... | ... | @@ -24,6 +24,20 @@ rtsRules = priority 3 $ do |
| 24 | 24 | (addRtsDummyVersion $ takeFileName rtsLibFilePath')
|
| 25 | 25 | rtsLibFilePath'
|
| 26 | 26 | |
| 27 | + -- Solve the recursive dependency between the rts and ghc-internal
|
|
| 28 | + -- on Windows by creating an import lib for the ghc-internal dll,
|
|
| 29 | + -- to be linked into the rts dll.
|
|
| 30 | + forM_ [Stage1, Stage2, Stage3 ] $ \ stage -> do
|
|
| 31 | + let buildPath = root -/- buildDir (rtsContext stage)
|
|
| 32 | + buildPath -/- "libHSghc-internal.dll.a" %> buildGhcInternalImportLib
|
|
| 33 | + |
|
| 34 | +buildGhcInternalImportLib :: FilePath -> Action ()
|
|
| 35 | +buildGhcInternalImportLib target = do
|
|
| 36 | + let input = "rts/win32/libHSghc-internal.def"
|
|
| 37 | + output = target -- the .dll.a import lib
|
|
| 38 | + need [input]
|
|
| 39 | + runBuilder Dlltool ["-d", input, "-l", output] [input] [output]
|
|
| 40 | + |
|
| 27 | 41 | -- Need symlinks generated by rtsRules.
|
| 28 | 42 | needRtsSymLinks :: Stage -> Set.Set Way -> Action ()
|
| 29 | 43 | needRtsSymLinks stage rtsWays
|
| ... | ... | @@ -131,8 +131,8 @@ AC_DEFUN([FP_SETUP_WINDOWS_TOOLCHAIN],[ |
| 131 | 131 | AR="${mingwbin}llvm-ar.exe"
|
| 132 | 132 | RANLIB="${mingwbin}llvm-ranlib.exe"
|
| 133 | 133 | OBJDUMP="${mingwbin}llvm-objdump.exe"
|
| 134 | - DLLTOOL="${mingwbin}llvm-dlltool.exe"
|
|
| 135 | 134 | WindresCmd="${mingwbin}llvm-windres.exe"
|
| 135 | + DlltoolCmd="${mingwbin}llvm-dlltool.exe"
|
|
| 136 | 136 | LLC="${mingwbin}llc.exe"
|
| 137 | 137 | OPT="${mingwbin}opt.exe"
|
| 138 | 138 | LLVMAS="${mingwbin}clang.exe"
|
| ... | ... | @@ -95,6 +95,7 @@ AC_DEFUN([FIND_GHC_TOOLCHAIN], |
| 95 | 95 | echo "--merge-objs=$MergeObjsCmd" >> acargs
|
| 96 | 96 | echo "--readelf=$READELF" >> acargs
|
| 97 | 97 | echo "--windres=$WindresCmd" >> acargs
|
| 98 | + echo "--dlltool=$DlltoolCmd" >> acargs
|
|
| 98 | 99 | echo "--llc=$LlcCmd" >> acargs
|
| 99 | 100 | echo "--opt=$OptCmd" >> acargs
|
| 100 | 101 | echo "--llvm-as=$LlvmAsCmd" >> acargs
|
| ... | ... | @@ -191,6 +191,7 @@ AC_DEFUN([PREP_TARGET_FILE],[ |
| 191 | 191 | PREP_MAYBE_SIMPLE_PROGRAM([OptCmd])
|
| 192 | 192 | PREP_MAYBE_PROGRAM([LlvmAsCmd], [LlvmAsFlags])
|
| 193 | 193 | PREP_MAYBE_SIMPLE_PROGRAM([WindresCmd])
|
| 194 | + PREP_MAYBE_SIMPLE_PROGRAM([DlltoolCmd])
|
|
| 194 | 195 | PREP_MAYBE_SIMPLE_PROGRAM([OtoolCmd])
|
| 195 | 196 | PREP_MAYBE_SIMPLE_PROGRAM([InstallNameToolCmd])
|
| 196 | 197 | PREP_MAYBE_STRING([TargetVendor_CPP])
|
| ... | ... | @@ -20,3 +20,4 @@ |
| 20 | 20 | /ghcautoconf.h.autoconf.in
|
| 21 | 21 | /ghcautoconf.h.autoconf
|
| 22 | 22 | /include/ghcautoconf.h
|
| 23 | +/win32/libHSghc-internal.def |
| 1 | +LIBRARY libHSghc-internal-@ProjectVersionForLib@.0-ghc@ProjectVersion@.dll
|
|
| 2 | + |
|
| 3 | +EXPORTS
|
|
| 4 | + init_ghc_hs_iface |