Duncan Coutts pushed to branch wip/dcoutts/windows-dlls-experimental at Glasgow Haskell Compiler / GHC
Commits:
-
f7379956
by Duncan Coutts at 2026-04-28T22:08:53+01:00
-
12f32953
by Duncan Coutts at 2026-04-28T22:08:53+01:00
-
f8aa77ce
by Duncan Coutts at 2026-04-28T22:08:53+01:00
-
38a785e6
by Duncan Coutts at 2026-04-28T22:08:53+01:00
-
146a2773
by David Eichmann at 2026-04-28T22:08:53+01:00
-
8515501c
by Duncan Coutts at 2026-04-28T22:08:54+01:00
-
f619d4b9
by Duncan Coutts at 2026-04-28T22:08:54+01:00
-
b10aafe7
by Duncan Coutts at 2026-04-28T22:08:54+01:00
-
d8139e1d
by Duncan Coutts at 2026-04-28T22:08:54+01:00
-
23a3a960
by Duncan Coutts at 2026-04-28T22:08:54+01:00
-
9b0ddfde
by Duncan Coutts at 2026-04-28T22:08:54+01:00
16 changed files:
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Stg/Utils.hs
- hadrian/src/Builder.hs
- hadrian/src/Hadrian/Builder.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Rules/Rts.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Program.hs
- rts/IOManager.h
- rts/Linker.c
- rts/RtsSymbols.c
- rts/RtsSymbols.h
Changes:
| ... | ... | @@ -668,25 +668,29 @@ importName |
| 668 | 668 | -- an unnamed Haskell package. This corresponds on Windows/PE to
|
| 669 | 669 | -- __declspec(dllimport) in C.
|
| 670 | 670 | | 'extern' NAME
|
| 671 | - { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage IsFunction) }
|
|
| 671 | + { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage
|
|
| 672 | + ForeignLabelIsFunction) }
|
|
| 672 | 673 | |
| 673 | 674 | -- A data label imported from another unamed shared library.
|
| 674 | 675 | -- This corresponds on Windows/PE to __declspec(dllimport) in C (but
|
| 675 | 676 | -- cmm doesn't know about data vs function symbols so we have to say).
|
| 676 | 677 | | 'extern' 'DATA' NAME
|
| 677 | - { ($3, mkForeignLabel $3 ForeignLabelInExternalPackage IsData) }
|
|
| 678 | + { ($3, mkForeignLabel $3 ForeignLabelInExternalPackage
|
|
| 679 | + ForeignLabelIsData) }
|
|
| 678 | 680 | |
| 679 | 681 | -- A code label imported from the shared library for a Haskell package
|
| 680 | 682 | -- with the given UnitId. Such labels behave as local when used within
|
| 681 | 683 | -- the specified unit, or as extern otherwise.
|
| 682 | 684 | | STRING NAME
|
| 683 | - { ($2, mkForeignLabel $2 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsFunction) }
|
|
| 685 | + { ($2, mkForeignLabel $2 (ForeignLabelInPackage (UnitId (mkFastString $1)))
|
|
| 686 | + ForeignLabelIsFunction) }
|
|
| 684 | 687 | |
| 685 | 688 | -- A data label imported from the shared library for a Haskell package
|
| 686 | 689 | -- with the given UnitId. Such labels behave as local when used within
|
| 687 | 690 | -- the specified unit, or as extern otherwise.
|
| 688 | 691 | | STRING 'DATA' NAME
|
| 689 | - { ($3, mkForeignLabel $3 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsData) }
|
|
| 692 | + { ($3, mkForeignLabel $3 (ForeignLabelInPackage (UnitId (mkFastString $1)))
|
|
| 693 | + ForeignLabelIsData) }
|
|
| 690 | 694 | |
| 691 | 695 | |
| 692 | 696 | names :: { [FastString] }
|
| ... | ... | @@ -3624,7 +3624,7 @@ compilerInfo dflags |
| 3624 | 3624 | ("target has RTS linker", showBool $ platformHasRTSLinker platform),
|
| 3625 | 3625 | ("Target default backend", show $ platformDefaultBackend platform),
|
| 3626 | 3626 | -- Whether or not we support @-dynamic-too@
|
| 3627 | - ("Support dynamic-too", showBool $ not isWindows),
|
|
| 3627 | + ("Support dynamic-too", "YES"),
|
|
| 3628 | 3628 | -- Whether or not we support the @-j@ flag with @--make@.
|
| 3629 | 3629 | ("Support parallel --make", "YES"),
|
| 3630 | 3630 | -- Whether or not we support "Foo from foo-0.1-XXX:Foo" syntax in
|
| ... | ... | @@ -3659,7 +3659,6 @@ compilerInfo dflags |
| 3659 | 3659 | showBool True = "YES"
|
| 3660 | 3660 | showBool False = "NO"
|
| 3661 | 3661 | platform = targetPlatform dflags
|
| 3662 | - isWindows = platformOS platform == OSMinGW32
|
|
| 3663 | 3662 | expandDirectories = expandToolDir (toolDir dflags) . expandTopDir (topDir dflags)
|
| 3664 | 3663 | query :: (Target -> a) -> a
|
| 3665 | 3664 | query f = f (rawTarget dflags)
|
| ... | ... | @@ -3757,11 +3756,6 @@ makeDynFlagsConsistent :: DynFlags -> (DynFlags, [Warn], [Located SDoc]) |
| 3757 | 3756 | -- ensure that a later change doesn't invalidate an earlier check.
|
| 3758 | 3757 | -- Be careful not to introduce potential loops!
|
| 3759 | 3758 | makeDynFlagsConsistent dflags
|
| 3760 | - -- Disable -dynamic-too on Windows (#8228, #7134, #5987)
|
|
| 3761 | - | os == OSMinGW32 && gopt Opt_BuildDynamicToo dflags
|
|
| 3762 | - = let dflags' = gopt_unset dflags Opt_BuildDynamicToo
|
|
| 3763 | - warn = "-dynamic-too is not supported on Windows"
|
|
| 3764 | - in loop dflags' warn
|
|
| 3765 | 3759 | -- Disable -dynamic-too if we are are compiling with -dynamic already, otherwise
|
| 3766 | 3760 | -- you get two dynamic object files (.o and .dyn_o). (#20436)
|
| 3767 | 3761 | | ways dflags `hasWay` WayDyn && gopt Opt_BuildDynamicToo dflags
|
| ... | ... | @@ -128,6 +128,9 @@ stripStgTicksTopE p = go |
| 128 | 128 | go other = other
|
| 129 | 129 | |
| 130 | 130 | -- | Do we allow the given top-level (static) ConApp?
|
| 131 | +--
|
|
| 132 | +-- Currently this is unconditionally True, but historically it has been more
|
|
| 133 | +-- complicated, so the mechanism to choose otherwise is still here for now.
|
|
| 131 | 134 | allowTopLevelConApp
|
| 132 | 135 | :: Platform
|
| 133 | 136 | -> Bool -- is Opt_ExternalDynamicRefs enabled?
|
| ... | ... | @@ -138,22 +141,18 @@ allowTopLevelConApp |
| 138 | 141 | allowTopLevelConApp platform ext_dyn_refs this_mod con args
|
| 139 | 142 | -- we're not using dynamic linking
|
| 140 | 143 | | not ext_dyn_refs = True
|
| 141 | - -- if the target OS is Windows, we only allow top-level ConApps if they don't
|
|
| 142 | - -- reference external names (Windows DLLs have a problem with static cross-DLL
|
|
| 143 | - -- refs)
|
|
| 144 | - | platformOS platform == OSMinGW32 = not is_external_con_app
|
|
| 144 | + |
|
| 145 | + -- On Windows, for now, always use top level constructor applications, and
|
|
| 146 | + -- rely on Mingw "pseudo relocations" to make this work. We might want to
|
|
| 147 | + -- have a flag to control this behaviour, because using pseudo-relocations
|
|
| 148 | + -- can be incompatible with some security restrictions, but note that
|
|
| 149 | + -- ghc-internal and everything would need to be rebuilt. Note also that
|
|
| 150 | + -- dynamic top level con apps increases symbol exports a lot.
|
|
| 151 | + | platformOS platform == OSMinGW32 = True
|
|
| 152 | + |
|
| 145 | 153 | -- otherwise, allowed
|
| 146 | 154 | -- Sylvain: shouldn't this be False when (ext_dyn_refs && is_external_con_app)?
|
| 147 | 155 | | otherwise = True
|
| 148 | - where
|
|
| 149 | - is_external_con_app = isDynLinkName platform this_mod (dataConName con) || any is_dll_arg args
|
|
| 150 | - |
|
| 151 | - -- NB: typePrimRep1 is legit because any free variables won't have
|
|
| 152 | - -- unlifted type (there are no unlifted things at top level)
|
|
| 153 | - is_dll_arg :: StgArg -> Bool
|
|
| 154 | - is_dll_arg (StgVarArg v) = isAddrRep (typePrimRep1 (idType v))
|
|
| 155 | - && isDynLinkName platform this_mod (idName v)
|
|
| 156 | - is_dll_arg _ = False
|
|
| 157 | 156 | |
| 158 | 157 | -- True of machine addresses; these are the things that don't work across DLLs.
|
| 159 | 158 | -- The key point here is that VoidRep comes out False, so that a top level
|
| ... | ... | @@ -346,11 +346,7 @@ instance H.Builder Builder where |
| 346 | 346 | |
| 347 | 347 | Haddock BuildPackage -> runHaddock path buildArgs buildInputs
|
| 348 | 348 | |
| 349 | - Ghc FindHsDependencies _ -> do
|
|
| 350 | - -- Use a response file for ghc -M invocations, to
|
|
| 351 | - -- avoid issues with command line size limit on
|
|
| 352 | - -- Windows (#26637)
|
|
| 353 | - runGhcWithResponse path buildArgs buildInputs
|
|
| 349 | + Ghc _ _ -> runGhcWithResponse path buildArgs buildInputs buildOptions
|
|
| 354 | 350 | |
| 355 | 351 | HsCpp -> captureStdout
|
| 356 | 352 | |
| ... | ... | @@ -394,16 +390,18 @@ runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do |
| 394 | 390 | writeFile' tmp $ escapeArgs fileInputs
|
| 395 | 391 | cmd [haddockPath] flagArgs ('@' : tmp)
|
| 396 | 392 | |
| 397 | -runGhcWithResponse :: FilePath -> [String] -> [FilePath] -> Action ()
|
|
| 398 | -runGhcWithResponse ghcPath flagArgs fileInputs = withTempFile $ \tmp -> do
|
|
| 399 | - |
|
| 400 | - writeFile' tmp $ escapeArgs fileInputs
|
|
| 401 | - |
|
| 402 | - -- We can't put the flags in a response file, because some flags
|
|
| 403 | - -- require empty arguments (such as the -dep-suffix flag), but
|
|
| 404 | - -- that isn't supported yet due to #26560.
|
|
| 405 | - cmd [ghcPath] flagArgs ('@' : tmp)
|
|
| 406 | - |
|
| 393 | +-- | Use a response file for ghc invocations to avoid issues with command line
|
|
| 394 | +-- size limit on Windows (#26637).
|
|
| 395 | +runGhcWithResponse :: FilePath -- ^ Path to ghc
|
|
| 396 | + -> [String] -- ^ Arguments passed on the command line
|
|
| 397 | + -> [FilePath] -- ^ Input file paths (passed via response file)
|
|
| 398 | + -> [CmdOption]
|
|
| 399 | + -> Action ()
|
|
| 400 | +runGhcWithResponse ghcPath buildArgs buildInputs buildOptions = withTempFile $ \tmp -> do
|
|
| 401 | + let tmpContents = escapeArgs buildInputs
|
|
| 402 | + putVerbose $ "Build Inputs (" <> tmp <> "): " <> show buildInputs
|
|
| 403 | + writeFile' tmp tmpContents
|
|
| 404 | + cmd [ghcPath] buildArgs ('@' : tmp) buildOptions
|
|
| 407 | 405 | |
| 408 | 406 | -- TODO: Some builders are required only on certain platforms. For example,
|
| 409 | 407 | -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
|
| ... | ... | @@ -29,7 +29,9 @@ import Hadrian.Utilities |
| 29 | 29 | |
| 30 | 30 | -- | This data structure captures all information relevant to invoking a builder.
|
| 31 | 31 | data BuildInfo = BuildInfo {
|
| 32 | - -- | Command line arguments.
|
|
| 32 | + -- | Command line arguments. Some builders (e.g. Ar, Ghc, Haddock) omit
|
|
| 33 | + -- buildInputs from buildArgs so that buildInputs can be passed separately
|
|
| 34 | + -- using a response file.
|
|
| 33 | 35 | buildArgs :: [String],
|
| 34 | 36 | -- | Input files.
|
| 35 | 37 | buildInputs :: [FilePath],
|
| ... | ... | @@ -82,11 +82,10 @@ arSupportsAtFile stage = Toolchain.arSupportsAtFile . tgtAr <$> targetStage stag |
| 82 | 82 | platformSupportsSharedLibs :: Action Bool
|
| 83 | 83 | -- FIXME: This is querying about the target but is named "platformXXX", targetSupportsSharedLibs would be better
|
| 84 | 84 | platformSupportsSharedLibs = do
|
| 85 | - windows <- isWinTarget
|
|
| 86 | 85 | ppc_linux <- (&&) <$> anyTargetArch [ ArchPPC ] <*> anyTargetOs [ OSLinux ]
|
| 87 | 86 | solaris <- (&&) <$> anyTargetArch [ ArchX86 ] <*> anyTargetOs [ OSSolaris2 ]
|
| 88 | 87 | javascript <- anyTargetArch [ ArchJavaScript ]
|
| 89 | - return $ not (windows || javascript || ppc_linux || solaris)
|
|
| 88 | + return $ not (javascript || ppc_linux || solaris)
|
|
| 90 | 89 | |
| 91 | 90 | -- | Does the target support threaded RTS?
|
| 92 | 91 | targetSupportsThreadedRts :: Action Bool
|
| ... | ... | @@ -12,7 +12,6 @@ import Hadrian.BuildPath |
| 12 | 12 | import Hadrian.Expression
|
| 13 | 13 | import Hadrian.Haskell.Cabal
|
| 14 | 14 | import Packages
|
| 15 | -import Rules.Rts
|
|
| 16 | 15 | import Settings
|
| 17 | 16 | import Target
|
| 18 | 17 | import Utilities
|
| ... | ... | @@ -88,14 +87,9 @@ parseToBuildSubdirectory root = do |
| 88 | 87 | -- * Registering
|
| 89 | 88 | |
| 90 | 89 | registerPackages :: [Context] -> Action ()
|
| 91 | -registerPackages ctxs = do
|
|
| 90 | +registerPackages ctxs =
|
|
| 92 | 91 | need =<< mapM pkgRegisteredLibraryFile ctxs
|
| 93 | 92 | |
| 94 | - -- Dynamic RTS library files need symlinks (Rules.Rts.rtsRules).
|
|
| 95 | - forM_ ctxs $ \ ctx -> when (package ctx == rts) $ do
|
|
| 96 | - ways <- interpretInContext ctx (getLibraryWays <> getRtsWays)
|
|
| 97 | - needRtsSymLinks (stage ctx) ways
|
|
| 98 | - |
|
| 99 | 93 | -- | Register a package and initialise the corresponding package database if
|
| 100 | 94 | -- need be. Note that we only register packages in 'Stage0' and 'Stage1'.
|
| 101 | 95 | registerPackageRules :: [(Resource, Int)] -> Stage -> Inplace -> Rules ()
|
| 1 | -{-# LANGUAGE MultiWayIf #-}
|
|
| 1 | +module Rules.Rts (rtsRules) where
|
|
| 2 | 2 | |
| 3 | -module Rules.Rts (rtsRules, needRtsSymLinks) where
|
|
| 4 | - |
|
| 5 | -import qualified Data.Set as Set
|
|
| 6 | - |
|
| 7 | -import Packages (rts)
|
|
| 8 | 3 | import Hadrian.Utilities
|
| 9 | 4 | import Settings.Builders.Common
|
| 10 | 5 | |
| ... | ... | @@ -12,18 +7,7 @@ import Settings.Builders.Common |
| 12 | 7 | -- library files (see Rules.Library.libraryRules).
|
| 13 | 8 | rtsRules :: Rules ()
|
| 14 | 9 | rtsRules = priority 3 $ do
|
| 15 | - -- Dynamic RTS library files need symlinks without the dummy version number.
|
|
| 16 | - -- This is for backwards compatibility (the old make build system omitted the
|
|
| 17 | - -- dummy version number).
|
|
| 18 | 10 | root <- buildRootRules
|
| 19 | - [ root -/- "**/libHSrts_*-ghc*.so",
|
|
| 20 | - root -/- "**/libHSrts_*-ghc*.dylib",
|
|
| 21 | - root -/- "**/libHSrts-ghc*.so",
|
|
| 22 | - root -/- "**/libHSrts-ghc*.dylib"]
|
|
| 23 | - |%> \ rtsLibFilePath' -> createFileLink
|
|
| 24 | - (addRtsDummyVersion $ takeFileName rtsLibFilePath')
|
|
| 25 | - rtsLibFilePath'
|
|
| 26 | - |
|
| 27 | 11 | -- Solve the recursive dependency between the rts and ghc-internal
|
| 28 | 12 | -- on Windows by creating an import lib for the ghc-internal dll,
|
| 29 | 13 | -- to be linked into the rts dll.
|
| ... | ... | @@ -37,35 +21,3 @@ buildGhcInternalImportLib target = do |
| 37 | 21 | output = target -- the .dll.a import lib
|
| 38 | 22 | need [input]
|
| 39 | 23 | runBuilder Dlltool ["-d", input, "-l", output] [input] [output] |
| 40 | - |
|
| 41 | --- Need symlinks generated by rtsRules.
|
|
| 42 | -needRtsSymLinks :: Stage -> Set.Set Way -> Action ()
|
|
| 43 | -needRtsSymLinks stage rtsWays
|
|
| 44 | - = forM_ (Set.filter (wayUnit Dynamic) rtsWays) $ \ way -> do
|
|
| 45 | - let ctx = Context stage rts way Final
|
|
| 46 | - distDir <- distDynDir ctx
|
|
| 47 | - rtsLibFile <- takeFileName <$> pkgLibraryFile ctx
|
|
| 48 | - need [removeRtsDummyVersion (distDir </> rtsLibFile)]
|
|
| 49 | - |
|
| 50 | -prefix, versionlessPrefix :: String
|
|
| 51 | -versionlessPrefix = "libHSrts"
|
|
| 52 | -prefix = versionlessPrefix ++ "-1.0.3"
|
|
| 53 | - |
|
| 54 | --- removeRtsDummyVersion "a/libHSrts-1.0-ghc1.2.3.4.so"
|
|
| 55 | --- == "a/libHSrts-ghc1.2.3.4.so"
|
|
| 56 | -removeRtsDummyVersion :: FilePath -> FilePath
|
|
| 57 | -removeRtsDummyVersion = replaceLibFilePrefix prefix versionlessPrefix
|
|
| 58 | - |
|
| 59 | --- addRtsDummyVersion "a/libHSrts-ghc1.2.3.4.so"
|
|
| 60 | --- == "a/libHSrts-1.0-ghc1.2.3.4.so"
|
|
| 61 | -addRtsDummyVersion :: FilePath -> FilePath
|
|
| 62 | -addRtsDummyVersion = replaceLibFilePrefix versionlessPrefix prefix
|
|
| 63 | - |
|
| 64 | -replaceLibFilePrefix :: String -> String -> FilePath -> FilePath
|
|
| 65 | -replaceLibFilePrefix oldPrefix newPrefix oldFilePath = let
|
|
| 66 | - oldFileName = takeFileName oldFilePath
|
|
| 67 | - newFileName = maybe
|
|
| 68 | - (error $ "Expected RTS library file to start with " ++ oldPrefix)
|
|
| 69 | - (newPrefix ++)
|
|
| 70 | - (stripPrefix oldPrefix oldFileName)
|
|
| 71 | - in replaceFileName oldFilePath newFileName |
| ... | ... | @@ -62,7 +62,6 @@ compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do |
| 62 | 62 | [ arg "-fwrite-ide-info"
|
| 63 | 63 | , arg "-hiedir", arg hie_path
|
| 64 | 64 | ]
|
| 65 | - , getInputs
|
|
| 66 | 65 | , arg "-o", arg =<< getOutput ]
|
| 67 | 66 | |
| 68 | 67 | compileC :: Args
|
| ... | ... | @@ -78,7 +77,6 @@ compileC = builder (Ghc CompileCWithGhc) ? do |
| 78 | 77 | , mconcat (map (map ("-optc" ++) <$>) ccArgs)
|
| 79 | 78 | , defaultGhcWarningsArgs
|
| 80 | 79 | , arg "-c"
|
| 81 | - , getInputs
|
|
| 82 | 80 | , arg "-o"
|
| 83 | 81 | , arg =<< getOutput ]
|
| 84 | 82 | |
| ... | ... | @@ -95,7 +93,6 @@ compileCxx = builder (Ghc CompileCppWithGhc) ? do |
| 95 | 93 | , mconcat (map (map ("-optcxx" ++) <$>) ccArgs)
|
| 96 | 94 | , defaultGhcWarningsArgs
|
| 97 | 95 | , arg "-c"
|
| 98 | - , getInputs
|
|
| 99 | 96 | , arg "-o"
|
| 100 | 97 | , arg =<< getOutput ]
|
| 101 | 98 |
| ... | ... | @@ -44,6 +44,7 @@ import Settings.Builders.SplitSections |
| 44 | 44 | import Settings.Builders.RunTest
|
| 45 | 45 | import Settings.Builders.Xelatex
|
| 46 | 46 | import Settings.Packages
|
| 47 | +import Settings.Program
|
|
| 47 | 48 | import Settings.Warnings
|
| 48 | 49 | import qualified Hadrian.Builder.Git
|
| 49 | 50 | import Settings.Builders.Win32Tarballs
|
| ... | ... | @@ -215,12 +216,32 @@ testsuitePackages = return ([ timeout | windowsHost ] ++ [ checkPpr, checkExact, |
| 215 | 216 | -- * We build 'profiling' way when stage > Stage0.
|
| 216 | 217 | -- * We build 'dynamic' way when stage > Stage0 and the platform supports it.
|
| 217 | 218 | defaultLibraryWays :: Ways
|
| 218 | -defaultLibraryWays = Set.fromList <$>
|
|
| 219 | - mconcat
|
|
| 220 | - [ pure [vanilla]
|
|
| 221 | - , notStage0 ? pure [profiling]
|
|
| 222 | - , notStage0 ? platformSupportsSharedLibs ? pure [dynamic, profilingDynamic]
|
|
| 223 | - ]
|
|
| 219 | +defaultLibraryWays = do
|
|
| 220 | + pkg <- getPackage
|
|
| 221 | + if isLibrary pkg
|
|
| 222 | + |
|
| 223 | + -- modules for libraries get built several ways
|
|
| 224 | + then Set.fromList <$>
|
|
| 225 | + mconcat
|
|
| 226 | + [ pure [vanilla]
|
|
| 227 | + , notStage0 ? pure [profiling]
|
|
| 228 | + , notStage0 ? platformSupportsSharedLibs
|
|
| 229 | + ? onlyDynGhcLibIfSupported
|
|
| 230 | + ? pure [dynamic, profilingDynamic]
|
|
| 231 | + ]
|
|
| 232 | + |
|
| 233 | + -- modules for executables get built only one way
|
|
| 234 | + else do stage <- getStage
|
|
| 235 | + Set.singleton <$> expr (programWay stage pkg)
|
|
| 236 | + |
|
| 237 | +-- | Only build the ghc library the dynamic way, if the platform supports it.
|
|
| 238 | +--
|
|
| 239 | +onlyDynGhcLibIfSupported :: Predicate
|
|
| 240 | +onlyDynGhcLibIfSupported = do
|
|
| 241 | + pkg <- getPackage
|
|
| 242 | + if pkg == compiler
|
|
| 243 | + then expr defaultDynamicGhcPrograms
|
|
| 244 | + else pure True
|
|
| 224 | 245 | |
| 225 | 246 | -- | Default build ways for the RTS.
|
| 226 | 247 | defaultRtsWays :: Ways
|
| ... | ... | @@ -310,7 +331,10 @@ defaultFlavour = Flavour |
| 310 | 331 | defaultDynamicGhcPrograms :: Action Bool
|
| 311 | 332 | defaultDynamicGhcPrograms = do
|
| 312 | 333 | supportsShared <- platformSupportsSharedLibs
|
| 313 | - return (not windowsHost && supportsShared)
|
|
| 334 | + winTarget <- isWinTarget
|
|
| 335 | + -- For now, don't build dynamic ghc on windows because we hit dll
|
|
| 336 | + -- symbol limits for the ghc library.
|
|
| 337 | + return (supportsShared && not winTarget)
|
|
| 314 | 338 | |
| 315 | 339 | -- | All 'Builder'-dependent command line arguments.
|
| 316 | 340 | defaultBuilderArgs :: Args
|
| ... | ... | @@ -321,6 +321,7 @@ rtsPackageArgs = package rts ? do |
| 321 | 321 | , Profiling `wayUnit` way ? arg "-DPROFILING"
|
| 322 | 322 | , Threaded `wayUnit` way ? arg "-DTHREADED_RTS"
|
| 323 | 323 | , notM targetSupportsSMP ? arg "-optc-DNOSMP"
|
| 324 | + , isWinHost ? arg "-optl-Wl,--disable-runtime-pseudo-reloc"
|
|
| 324 | 325 | |
| 325 | 326 | -- See Note [AutoApply.cmm for vectors] in genapply/Main.hs
|
| 326 | 327 | --
|
| 1 | 1 | module Settings.Program
|
| 2 | 2 | ( programContext
|
| 3 | + , programWay
|
|
| 3 | 4 | , ghcWithInterpreter
|
| 4 | 5 | ) where
|
| 5 | 6 | |
| ... | ... | @@ -17,18 +18,21 @@ import Settings.Builders.Common (anyTargetOs, anyTargetArch, isArmTarget) |
| 17 | 18 | -- get a context/contexts for a given stage and package.
|
| 18 | 19 | programContext :: Stage -> Package -> Action Context
|
| 19 | 20 | programContext stage pkg = do
|
| 20 | - profiled <- askGhcProfiled stage
|
|
| 21 | - dynGhcProgs <- askDynGhcPrograms --dynamicGhcPrograms =<< flavour
|
|
| 22 | - return $ Context stage pkg (wayFor profiled dynGhcProgs) Final
|
|
| 21 | + way <- programWay stage pkg
|
|
| 22 | + return $ Context stage pkg way Final
|
|
| 23 | 23 | |
| 24 | - where wayFor prof dyn
|
|
| 25 | - | prof && dyn = profilingDynamic
|
|
| 26 | - | pkg == ghc && prof && notStage0 stage = profiling
|
|
| 27 | - | dyn && notStage0 stage = dynamic
|
|
| 28 | - | otherwise = vanilla
|
|
| 24 | +programWay :: Stage -> Package -> Action Way
|
|
| 25 | +programWay stage pkg =
|
|
| 26 | + wayFor <$> askGhcProfiled stage <*> askDynGhcPrograms
|
|
| 27 | + where
|
|
| 28 | + wayFor prof dyn
|
|
| 29 | + | prof && dyn = profilingDynamic
|
|
| 30 | + | pkg == ghc && prof && notStage0 stage = profiling
|
|
| 31 | + | dyn && notStage0 stage = dynamic
|
|
| 32 | + | otherwise = vanilla
|
|
| 29 | 33 | |
| 30 | - notStage0 (Stage0 {}) = False
|
|
| 31 | - notStage0 _ = True
|
|
| 34 | + notStage0 (Stage0 {}) = False
|
|
| 35 | + notStage0 _ = True
|
|
| 32 | 36 | |
| 33 | 37 | -- | When cross compiling, enable for stage0 to get ghci
|
| 34 | 38 | -- support. But when not cross compiling, disable for
|
| ... | ... | @@ -21,6 +21,15 @@ |
| 21 | 21 | |
| 22 | 22 | #include "sm/GC.h" // for evac_fn
|
| 23 | 23 | |
| 24 | +#if defined(mingw32_HOST_OS)
|
|
| 25 | +/* Global var (only on Windows) that is exported (hence before BeginPrivate.h)
|
|
| 26 | + * to be shared with the I/O code in the base library to tell us which style
|
|
| 27 | + * of I/O manager we are using: one that uses the Windows native API HANDLEs,
|
|
| 28 | + * or one that uses Posix style fds.
|
|
| 29 | + */
|
|
| 30 | +extern bool rts_IOManagerIsWin32Native;
|
|
| 31 | +#endif
|
|
| 32 | + |
|
| 24 | 33 | #include "BeginPrivate.h"
|
| 25 | 34 | |
| 26 | 35 | /* The ./configure gives us a set of CPP flags, one for each named I/O manager:
|
| ... | ... | @@ -160,14 +169,6 @@ typedef enum { |
| 160 | 169 | /* Global var to tell us which I/O manager impl we are using */
|
| 161 | 170 | extern IOManagerType iomgr_type;
|
| 162 | 171 | |
| 163 | -#if defined(mingw32_HOST_OS)
|
|
| 164 | -/* Global var (only on Windows) that is exported to be shared with the I/O code
|
|
| 165 | - * in the base library to tell us which style of I/O manager we are using: one
|
|
| 166 | - * that uses the Windows native API HANDLEs, or one that uses Posix style fds.
|
|
| 167 | - */
|
|
| 168 | -extern bool rts_IOManagerIsWin32Native;
|
|
| 169 | -#endif
|
|
| 170 | - |
|
| 171 | 172 | |
| 172 | 173 | /* The CapIOManager is the per-capability data structure belonging to the I/O
|
| 173 | 174 | * manager. It is defined in full in IOManagerInternals.h. The opaque forward
|
| ... | ... | @@ -478,16 +478,7 @@ initLinker_ (int retain_cafs) |
| 478 | 478 | symhash = allocStrHashTable();
|
| 479 | 479 | |
| 480 | 480 | /* populate the symbol table with stuff from the RTS */
|
| 481 | - IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
|
|
| 482 | - for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
|
|
| 483 | - IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
|
|
| 484 | - if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
|
|
| 485 | - symhash, sym->lbl, sym->addr,
|
|
| 486 | - sym->strength, sym->type, 0, NULL)) {
|
|
| 487 | - barf("ghciInsertSymbolTable failed");
|
|
| 488 | - }
|
|
| 489 | - }
|
|
| 490 | - IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
|
|
| 481 | + initLinkerRtsSyms(symhash);
|
|
| 491 | 482 | |
| 492 | 483 | /* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
|
| 493 | 484 | * that can be overrided by linking in an object with a corresponding
|
| ... | ... | @@ -9,6 +9,8 @@ |
| 9 | 9 | #include "ghcplatform.h"
|
| 10 | 10 | #include "Rts.h"
|
| 11 | 11 | #include "RtsSymbols.h"
|
| 12 | +#include "LinkerInternals.h"
|
|
| 13 | +#include "PathUtils.h"
|
|
| 12 | 14 | |
| 13 | 15 | #include "TopHandler.h"
|
| 14 | 16 | #include "HsFFI.h"
|
| ... | ... | @@ -51,6 +53,19 @@ extern char **environ; |
| 51 | 53 | |
| 52 | 54 | /* -----------------------------------------------------------------------------
|
| 53 | 55 | * Symbols to be inserted into the RTS symbol table.
|
| 56 | + *
|
|
| 57 | + * Note [Naming Scheme for Symbol Macros]
|
|
| 58 | + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 59 | + *
|
|
| 60 | + * SymI_*: symbol is internal to the RTS. It resides in an object
|
|
| 61 | + * file/library that is statically.
|
|
| 62 | + * SymE_*: symbol is external to the RTS library. It might be linked
|
|
| 63 | + * dynamically.
|
|
| 64 | + *
|
|
| 65 | + * Sym*_HasProto : the symbol prototype is imported in an include file
|
|
| 66 | + * or defined explicitly
|
|
| 67 | + * Sym*_NeedsProto: the symbol is undefined and we add a dummy
|
|
| 68 | + * default proto extern void sym(void);
|
|
| 54 | 69 | */
|
| 55 | 70 | |
| 56 | 71 | #define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
|
| ... | ... | @@ -162,7 +177,7 @@ extern char **environ; |
| 162 | 177 | SymI_HasProto(stg_asyncWritezh) \
|
| 163 | 178 | SymI_HasProto(stg_asyncDoProczh) \
|
| 164 | 179 | SymI_HasProto(rts_InstallConsoleEvent) \
|
| 165 | - SymI_HasProto(rts_IOManagerIsWin32Native) \
|
|
| 180 | + SymI_HasDataProto(rts_IOManagerIsWin32Native) \
|
|
| 166 | 181 | SymI_HasProto(rts_ConsoleHandlerDone) \
|
| 167 | 182 | SymI_NeedsProto(__mingw_module_is_dll) \
|
| 168 | 183 | RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \
|
| ... | ... | @@ -912,7 +927,7 @@ extern char **environ; |
| 912 | 927 | SymI_HasProto(freeExecPage) \
|
| 913 | 928 | SymI_HasProto(getAllocations) \
|
| 914 | 929 | SymI_HasProto(revertCAFs) \
|
| 915 | - SymI_HasProto(RtsFlags) \
|
|
| 930 | + SymI_HasDataProto(RtsFlags) \
|
|
| 916 | 931 | SymI_NeedsDataProto(rts_breakpoint_io_action) \
|
| 917 | 932 | SymI_NeedsDataProto(rts_stop_next_breakpoint) \
|
| 918 | 933 | SymI_NeedsDataProto(rts_stop_on_exception) \
|
| ... | ... | @@ -923,9 +938,9 @@ extern char **environ; |
| 923 | 938 | SymI_NeedsProto(rts_enableStopAfterReturn) \
|
| 924 | 939 | SymI_NeedsProto(rts_disableStopAfterReturn) \
|
| 925 | 940 | SymI_HasProto(stopTimer) \
|
| 926 | - SymI_HasProto(n_capabilities) \
|
|
| 927 | - SymI_HasProto(max_n_capabilities) \
|
|
| 928 | - SymI_HasProto(enabled_capabilities) \
|
|
| 941 | + SymI_HasDataProto(n_capabilities) \
|
|
| 942 | + SymI_HasDataProto(max_n_capabilities) \
|
|
| 943 | + SymI_HasDataProto(enabled_capabilities) \
|
|
| 929 | 944 | SymI_HasDataProto(stg_traceEventzh) \
|
| 930 | 945 | SymI_HasDataProto(stg_traceMarkerzh) \
|
| 931 | 946 | SymI_HasDataProto(stg_traceBinaryEventzh) \
|
| ... | ... | @@ -1143,12 +1158,27 @@ extern char **environ; |
| 1143 | 1158 | SymI_HasProto(hs_word2float64)
|
| 1144 | 1159 | |
| 1145 | 1160 | |
| 1146 | -/* entirely bogus claims about types of these symbols */
|
|
| 1147 | -#define SymI_NeedsProto(vvv) extern void vvv(void);
|
|
| 1148 | -#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
|
|
| 1149 | -#define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
|
|
| 1150 | -#define SymE_NeedsDataProto(vvv) SymI_NeedsDataProto(vvv);
|
|
| 1151 | -#define SymE_HasProto(vvv) SymI_HasProto(vvv);
|
|
| 1161 | +/* Declare prototypes for the symbols that need it, so we can refer
|
|
| 1162 | + * to them in the rtsSyms table below.
|
|
| 1163 | + *
|
|
| 1164 | + * In particular, for the external ones (SymE_*) we use the dllimport attribute
|
|
| 1165 | + * to indicate that (on Windows) they come from external DLLs. This attribute
|
|
| 1166 | + * is ignored on other platforms.
|
|
| 1167 | + *
|
|
| 1168 | + * The claims about the types of these symbols are entirely bogus.
|
|
| 1169 | + */
|
|
| 1170 | +#if defined(mingw32_HOST_OS) && defined(DYNAMIC)
|
|
| 1171 | +#define DLLIMPORT __attribute__((dllimport))
|
|
| 1172 | +#else
|
|
| 1173 | +#define DLLIMPORT /**/
|
|
| 1174 | +#endif
|
|
| 1175 | + |
|
| 1176 | +#define SymI_NeedsProto(vvv) extern void vvv(void);
|
|
| 1177 | +#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
|
|
| 1178 | +#define SymE_NeedsProto(vvv) extern DLLIMPORT void vvv(void);
|
|
| 1179 | +#define SymE_NeedsDataProto(vvv) extern DLLIMPORT StgWord vvv[];
|
|
| 1180 | + |
|
| 1181 | +#define SymE_HasProto(vvv) /**/
|
|
| 1152 | 1182 | #define SymI_HasProto(vvv) /**/
|
| 1153 | 1183 | #define SymI_HasDataProto(vvv) /**/
|
| 1154 | 1184 | #define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
|
| ... | ... | @@ -1177,6 +1207,8 @@ RTS_SYMBOLS_PRIM |
| 1177 | 1207 | #undef SymE_NeedsProto
|
| 1178 | 1208 | #undef SymE_NeedsDataProto
|
| 1179 | 1209 | |
| 1210 | +/* See Note [Naming Scheme for Symbol Macros] */
|
|
| 1211 | + |
|
| 1180 | 1212 | #define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
|
| 1181 | 1213 | (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
|
| 1182 | 1214 | #define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
|
| ... | ... | @@ -1197,7 +1229,16 @@ RTS_SYMBOLS_PRIM |
| 1197 | 1229 | { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
|
| 1198 | 1230 | (void*)(&(xxx)), strength, ty },
|
| 1199 | 1231 | |
| 1200 | -RtsSymbolVal rtsSyms[] = {
|
|
| 1232 | + |
|
| 1233 | +/* Populate the symbol table with stuff from the RTS. */
|
|
| 1234 | +void initLinkerRtsSyms (StrHashTable *symhash) {
|
|
| 1235 | + |
|
| 1236 | + /* The address of data symbols with the dllimport attribute are not
|
|
| 1237 | + * compile-time constants and so cannot be used in constant initialisers.
|
|
| 1238 | + * For this reason, rtsSyms is a local variable within this function
|
|
| 1239 | + * rather than a global constant (as it was historically).
|
|
| 1240 | + */
|
|
| 1241 | + const RtsSymbolVal rtsSyms[] = {
|
|
| 1201 | 1242 | RTS_SYMBOLS
|
| 1202 | 1243 | RTS_RET_SYMBOLS
|
| 1203 | 1244 | RTS_POSIX_ONLY_SYMBOLS
|
| ... | ... | @@ -1212,7 +1253,19 @@ RtsSymbolVal rtsSyms[] = { |
| 1212 | 1253 | RTS_SYMBOLS_PRIM
|
| 1213 | 1254 | SymI_HasDataProto(nonmoving_write_barrier_enabled)
|
| 1214 | 1255 | { 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
|
| 1215 | -};
|
|
| 1256 | + };
|
|
| 1257 | + |
|
| 1258 | + IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
|
|
| 1259 | + for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
|
|
| 1260 | + IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
|
|
| 1261 | + if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
|
|
| 1262 | + symhash, sym->lbl, sym->addr,
|
|
| 1263 | + sym->strength, sym->type, 0, NULL)) {
|
|
| 1264 | + barf("ghciInsertSymbolTable failed");
|
|
| 1265 | + }
|
|
| 1266 | + }
|
|
| 1267 | + IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
|
|
| 1268 | +}
|
|
| 1216 | 1269 | |
| 1217 | 1270 | |
| 1218 | 1271 | // Note [Extra RTS symbols]
|
| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #pragma once
|
| 10 | 10 | |
| 11 | 11 | #include "ghcautoconf.h"
|
| 12 | +#include "Hash.h"
|
|
| 12 | 13 | |
| 13 | 14 | #if defined(LEADING_UNDERSCORE)
|
| 14 | 15 | #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
|
| ... | ... | @@ -46,7 +47,7 @@ typedef struct _RtsSymbolVal { |
| 46 | 47 | SymType type;
|
| 47 | 48 | } RtsSymbolVal;
|
| 48 | 49 | |
| 49 | -extern RtsSymbolVal rtsSyms[];
|
|
| 50 | +void initLinkerRtsSyms (StrHashTable *symhash);
|
|
| 50 | 51 | |
| 51 | 52 | extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
|
| 52 | 53 |