Commit 5266ab90 authored by Tamar Christina's avatar Tamar Christina Committed by Ben Gamari

Remove dll-split.

This patch removes dll-split from the code base, the reason is dll-split
no longer makes any sense. It was designed to split a dll in two, but we
now already have many more symbols than would fit inside two dlls. So we
need a third one. This means there's no point in having to maintain this
list as it'll never work anyway and the solution isn't scalable.

Test Plan: ./validate

Reviewers: austin, bgamari

Reviewed By: bgamari

Subscribers: rwbarton, thomie, #ghc_windows_task_force

GHC Trac Issues: #5987

Differential Revision: https://phabricator.haskell.org/D3882
parent db3a8e16
......@@ -428,154 +428,6 @@ compiler_stage1_SplitSections = NO
compiler_stage2_SplitSections = NO
compiler_stage3_SplitSections = NO
# There are too many symbols in the ghc package for a Windows DLL
# (due to a limitation of bfd ld, see Trac #5987). We therefore need to split
# some of the modules off into a separate DLL. This clump are the modules
# reachable from DynFlags:
compiler_stage2_dll0_START_MODULE = DynFlags
compiler_stage2_dll0_MODULES = \
Annotations \
ApiAnnotation \
Avail \
Bag \
BasicTypes \
Binary \
BinFingerprint \
BooleanFormula \
BufWrite \
ByteCodeTypes \
Class \
CmdLineParser \
CmmType \
CoAxiom \
ConLike \
Coercion \
Config \
Constants \
CoreArity \
CoreFVs \
CoreSubst \
CoreOpt \
CoreSyn \
CoreTidy \
CoreUnfold \
CoreUtils \
CoreSeq \
CoreStats \
CostCentre \
DataCon \
Demand \
Digraph \
DriverPhases \
DynFlags \
Encoding \
EnumSet \
ErrUtils \
Exception \
FamInstEnv \
FastFunctions \
FastMutInt \
FastString \
FastStringEnv \
FieldLabel \
FileCleanup \
Fingerprint \
FiniteMap \
ForeignCall \
FV \
Hooks \
HsBinds \
HsDecls \
HsDoc \
HsExpr \
HsImpExp \
HsLit \
PlaceHolder \
HsExtension \
PmExpr \
HsPat \
HsSyn \
HsTypes \
HsUtils \
HscTypes \
IOEnv \
NameCache \
Id \
IdInfo \
IfaceSyn \
IfaceType \
InteractiveEvalTypes \
Json \
ToIface \
InstEnv \
Kind \
KnownUniques \
Lexeme \
ListSetOps \
Literal \
Maybes \
MkCore \
MkId \
Module \
MonadUtils \
Name \
NameEnv \
NameSet \
OccName \
OccurAnal \
OptCoercion \
OrdList \
Outputable \
PackageConfig \
Packages \
Pair \
Panic \
PatSyn \
PipelineMonad \
Platform \
PlatformConstants \
PprColour \
PprCore \
PrelNames \
PrelRules \
Pretty \
PrimOp \
RepType \
RdrName \
Rules \
SrcLoc \
StringBuffer \
SysTools.Terminal \
TcEvidence \
TcRnTypes \
TcType \
TrieMap \
TyCon \
Type \
TyCoRep \
TysPrim \
TysWiredIn \
Unify \
UniqDFM \
UniqDSet \
UniqFM \
UniqSet \
UniqSupply \
Unique \
Util \
Var \
VarEnv \
VarSet
ifeq "$(GhcWithInterpreter)" "YES"
# These files are reacheable from DynFlags
# only by GHCi-enabled code (see #9552)
compiler_stage2_dll0_MODULES += # none
endif
compiler_stage2_dll0_HS_OBJS = \
$(patsubst %,compiler/stage2/build/%.$(dyn_osuf),$(subst .,/,$(compiler_stage2_dll0_MODULES)))
# if stage is set to something other than "1" or "", disable stage 1
# See Note [Stage1Only vs stage=1] in mk/config.mk.in.
ifneq "$(filter-out 1,$(stage))" ""
......
......@@ -766,14 +766,6 @@ data DynFlags = DynFlags {
dynObjectSuf :: String,
dynHiSuf :: String,
-- Packages.isDllName needs to know whether a call is within a
-- single DLL or not. Normally it does this by seeing if the call
-- is to the same package, but for the ghc package, we split the
-- package between 2 DLLs. The dllSplit tells us which sets of
-- modules are in which package.
dllSplitFile :: Maybe FilePath,
dllSplit :: Maybe [Set String],
outputFile :: Maybe String,
dynOutputFile :: Maybe String,
outputHi :: Maybe String,
......@@ -1606,9 +1598,6 @@ defaultDynFlags mySettings =
dynObjectSuf = "dyn_" ++ phaseInputExt StopLn,
dynHiSuf = "dyn_hi",
dllSplitFile = Nothing,
dllSplit = Nothing,
pluginModNames = [],
pluginModNameOpts = [],
frontendPluginOpts = [],
......@@ -2422,27 +2411,13 @@ parseDynamicFlagsFull activeFlags cmdline dflags0 args = do
let (dflags5, consistency_warnings) = makeDynFlagsConsistent dflags4
dflags6 <- case dllSplitFile dflags5 of
Nothing -> return (dflags5 { dllSplit = Nothing })
Just f ->
case dllSplit dflags5 of
Just _ ->
-- If dllSplit is out of date then it would have
-- been set to Nothing. As it's a Just, it must be
-- up-to-date.
return dflags5
Nothing ->
do xs <- liftIO $ readFile f
let ss = map (Set.fromList . words) (lines xs)
return $ dflags5 { dllSplit = Just ss }
-- Set timer stats & heap size
when (enableTimeStats dflags6) $ liftIO enableTimingStats
case (ghcHeapSize dflags6) of
when (enableTimeStats dflags5) $ liftIO enableTimingStats
case (ghcHeapSize dflags5) of
Just x -> liftIO (setHeapSize x)
_ -> return ()
dflags7 <- liftIO $ setLogAction dflags6
dflags7 <- liftIO $ setLogAction dflags5
liftIO $ setUnsafeGlobalDynFlags dflags7
......@@ -2751,9 +2726,6 @@ dynamic_flags_deps = [
(noArg (\d -> d { ghcLink=LinkStaticLib }))
, make_ord_flag defGhcFlag "dynload" (hasArg parseDynLibLoaderMode)
, make_ord_flag defGhcFlag "dylib-install-name" (hasArg setDylibInstallName)
-- -dll-split is an internal flag, used only during the GHC build
, make_ord_flag defHiddenFlag "dll-split"
(hasArg (\f d -> d { dllSplitFile = Just f, dllSplit = Nothing }))
------- Libraries ---------------------------------------------------
, make_ord_flag defFlag "L" (Prefix addLibraryPath)
......
......@@ -2,8 +2,6 @@
-- NB: this module is SOURCE-imported by DynFlags, and should primarily
-- refer to *types*, rather than *code*
-- If you import too muchhere , then the revolting compiler_stage2_dll0_MODULES
-- stuff in compiler/ghc.mk makes DynFlags link to too much stuff
{-# LANGUAGE CPP #-}
module Hooks ( Hooks
......
......@@ -71,6 +71,7 @@ import UniqSet
import Module
import Util
import Panic
import Platform
import Outputable
import Maybes
......@@ -1966,16 +1967,19 @@ isDllName dflags this_mod name
-- In the mean time, always force dynamic indirections to be
-- generated: when the module name isn't the module being
-- compiled, references are dynamic.
= if mod /= this_mod
then True
else case dllSplit dflags of
Nothing -> False
Just ss ->
let findMod m = let modStr = moduleNameString (moduleName m)
in case find (modStr `Set.member`) ss of
Just i -> i
Nothing -> panic ("Can't find " ++ modStr ++ "in DLL split")
in findMod mod /= findMod this_mod
= case platformOS $ targetPlatform dflags of
-- On Windows the hack for #8696 makes it unlinkable.
-- As the entire setup of the code from Cmm down to the RTS expects
-- the use of trampolines for the imported functions only when
-- doing intra-package linking, e.g. refering to a symbol defined in the same
-- package should not use a trampoline.
-- I much rather have dynamic TH not supported than the entire Dynamic linking
-- not due to a hack.
-- Also not sure this would break on Windows anyway.
OSMinGW32 -> moduleUnitId mod /= moduleUnitId this_mod
-- For the other platforms, still perform the hack
_ -> mod /= this_mod
| otherwise = False -- no, it is not even an external name
......
......@@ -679,7 +679,6 @@ BUILD_DIRS += utils/testremove
BUILD_DIRS += utils/ghctags
BUILD_DIRS += utils/check-api-annotations
BUILD_DIRS += utils/check-ppr
BUILD_DIRS += utils/dll-split
BUILD_DIRS += utils/ghc-cabal
BUILD_DIRS += utils/hpc
BUILD_DIRS += utils/runghc
......
......@@ -125,7 +125,7 @@ ifneq "$$($1_NO_CHECK)" "YES"
"$$(ghc-cabal_INPLACE)" check $1
endif
endif
"$$(ghc-cabal_INPLACE)" configure $1 $2 "$$($1_$2_dll0_MODULES)" --with-ghc="$$($1_$2_HC_CONFIG)" --with-ghc-pkg="$$($1_$2_GHC_PKG)" $$($1_CONFIGURE_OPTS) $$($1_$2_CONFIGURE_OPTS)
"$$(ghc-cabal_INPLACE)" configure $1 $2 --with-ghc="$$($1_$2_HC_CONFIG)" --with-ghc-pkg="$$($1_$2_GHC_PKG)" $$($1_CONFIGURE_OPTS) $$($1_$2_CONFIGURE_OPTS)
ifeq "$$($1_$2_PROG)" ""
$$(call cmd,$1_$2_GHC_PKG) update -v0 --force $$($1_$2_GHC_PKG_OPTS) $1/$2/inplace-pkg-config
endif
......
......@@ -23,18 +23,10 @@ $(call hs-objs,$1,$2,$3)
# The .a/.so library file, indexed by two different sets of vars:
# the first is indexed by the dir, distdir and way
# the second is indexed by the package id, distdir and way
$1_$2_$3_LIB_FILE = libHS$$($1_$2_COMPONENT_ID)$$($3_libsuf)
$1_$2_$3_LIB_FILE = libHS$$($1_$2_COMPONENT_ID)$(subst .,%,$$($3_libsuf))
$1_$2_$3_LIB = $1/$2/build/$$($1_$2_$3_LIB_FILE)
$$($1_$2_COMPONENT_ID)_$2_$3_LIB = $$($1_$2_$3_LIB)
ifeq "$$(TargetOS_CPP)" "mingw32"
ifneq "$$($1_$2_dll0_HS_OBJS)" ""
$1_$2_$3_LIB0_ROOT = HS$$($1_$2_COMPONENT_ID)-0$$($3_libsuf)
$1_$2_$3_LIB0_NAME = lib$$($1_$2_$3_LIB0_ROOT)
$1_$2_$3_LIB0 = $1/$2/build/$$($1_$2_$3_LIB0_NAME)
endif
endif
# Note [inconsistent distdirs]
#
# hack: the DEPS_LIBS mechanism assumes that the distdirs for packages
......@@ -62,32 +54,11 @@ $1_$2_$3_ALL_OBJS = $$($1_$2_$3_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS)
ifeq "$3" "dyn"
ifneq "$$($1_$2_dll0_MODULES)" ""
$$($1_$2_$3_LIB) : $1/$2/dll-split.stamp
ifneq "$$($1_$2_$3_LIB0)" ""
$$($1_$2_$3_LIB0) : $1/$2/dll-split.stamp
endif
endif
$1/$2/dll-split.stamp: $$($1_$2_depfile_haskell) $$$$(dll-split_INPLACE)
$$(dll-split_INPLACE) $$< "$$($1_$2_dll0_START_MODULE)" "$$($1_$2_dll0_MODULES)"
touch $$@
# Link a dynamic library
# On windows we have to supply the extra libs this one links to when building it.
ifeq "$$(TargetOS_CPP)" "mingw32"
$$($1_$2_$3_LIB) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
ifneq "$$($1_$2_$3_LIB0)" ""
$$(call build-dll,$1,$2,$3,-L$1/$2/build -l$$($1_$2_$3_LIB0_ROOT),$$(filter-out $$($1_$2_dll0_HS_OBJS),$$($1_$2_$3_HS_OBJS)) $$($1_$2_$3_NON_HS_OBJS),$$@)
else
$$(call build-dll,$1,$2,$3,,$$($1_$2_$3_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$@)
endif
ifneq "$$($1_$2_$3_LIB0)" ""
$$($1_$2_$3_LIB) : $$($1_$2_$3_LIB0)
$$($1_$2_$3_LIB0) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
$$(call build-dll,$1,$2,$3,,$$($1_$2_dll0_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$($1_$2_$3_LIB0))
endif
$$(call build-dll,$1,$2,$3,-L$1/$2/build,,$$($1_$2_$3_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),"$$@","NO","$$($1_PACKAGE)","$$($1_$2_VERSION)")
else # ifneq "$$(TargetOS_CPP)" "mingw32"
$$($1_$2_$3_LIB) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
......@@ -116,14 +87,6 @@ else
endif
$$(call removeFiles,$$@.contents)
ifeq "$$(TargetOS_CPP)" "mingw32"
ifneq "$$($1_$2_$3_LIB0)" ""
$$($1_$2_$3_LIB) : $$($1_$2_$3_LIB0)
$$($1_$2_$3_LIB0) :
$$(call cmd,$1_$2_AR) $$($1_$2_AR_OPTS) $$($1_$2_EXTRA_AR_ARGS) $$@
endif
endif
endif # "$3" "dyn"
$(call all-target,$1_$2,all_$1_$2_$3)
......@@ -133,7 +96,7 @@ $(call all-target,$1_$2_$3,$$($1_$2_$3_LIB))
ifneq "$4" "0"
BINDIST_HI += $$($1_$2_$3_HI)
BINDIST_LIBS += $$($1_$2_$3_LIB)
BINDIST_LIBS += $$($1_$2_$3_LIB0)
# Need to put the split libs and import libraries here
endif
ifeq "$$($1_$2_SplitSections)" "YES"
......
......@@ -177,14 +177,6 @@ $1_$2_$3_ALL_HC_OPTS = \
$$(if $$(findstring YES,$$($1_$2_SplitSections)),$$(if $$(findstring dyn,$3),,-split-sections),) \
$$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),$$(if $$(findstring v,$3),-dynamic-too))
ifeq "$3" "dyn"
ifeq "$$(HostOS_CPP)" "mingw32"
ifneq "$$($1_$2_dll0_MODULES)" ""
$1_$2_$3_ALL_HC_OPTS += -dll-split $1/$2/dll-split
endif
endif
endif
$1_$2_$3_ALL_CC_OPTS = \
$$(WAY_$3_CC_OPTS) \
$$($1_$2_DIST_GCC_CC_OPTS) \
......
module Main (main) where
import Control.Monad
import Data.Function
import Data.List
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
import Data.Set (Set)
import qualified Data.Set as Set
import System.Environment
import System.Exit
import System.FilePath
main :: IO ()
main = do args <- getArgs
case args of
[depfile, startModule, reachableModules] ->
doit depfile
(Module startModule)
(Set.fromList $ map Module $ words reachableModules)
_ -> error "dll-split: Bad args"
doit :: FilePath -> Module -> Set Module -> IO ()
doit depfile startModule expectedReachableMods
= do xs <- readFile depfile
let ys = catMaybes $ map mkEdge $ lines xs
mapping = mkMap ys
actualReachableMods = reachable mapping startModule
unless (actualReachableMods == expectedReachableMods) $ do
let extra = actualReachableMods Set.\\ expectedReachableMods
redundant = expectedReachableMods Set.\\ actualReachableMods
tellSet name set = unless (Set.null set) $
let ms = map moduleName (Set.toList set)
in putStrLn (name ++ ": " ++ unwords ms)
putStrLn ("Reachable modules from " ++ moduleName startModule
++ " out of date")
putStrLn "Please fix compiler/ghc.mk, or building DLLs on Windows may break (#7780)"
tellSet "Redundant modules" redundant
tellSet "Extra modules" extra
exitFailure
newtype Module = Module String
deriving (Eq, Ord)
moduleName :: Module -> String
moduleName (Module name) = name
-- Given:
-- compiler/stage2/build/X86/Regs.o : compiler/stage2/build/CodeGen/Platform.hi
-- Produce:
-- Just ("X86.Regs", "CodeGen.Platform")
mkEdge :: String -> Maybe (Module, Module)
mkEdge str = case words str of
[from, ":", to]
| Just from' <- getModule from
, Just to' <- getModule to ->
Just (from', to')
_ ->
Nothing
where getModule xs
= case stripPrefix "compiler/stage2/build/" xs of
Just xs' ->
let name = filePathToModuleName $ dropExtension xs'
in Just $ Module name
Nothing -> Nothing
filePathToModuleName = map filePathToModuleNameChar
filePathToModuleNameChar '/' = '.'
filePathToModuleNameChar c = c
mkMap :: [(Module, Module)] -> (Map Module (Set Module))
mkMap edges = let groupedEdges = groupBy ((==) `on` fst) $ sort edges
mkEdgeMap ys = (fst (head ys), Set.fromList (map snd ys))
in Map.fromList $ map mkEdgeMap groupedEdges
reachable :: Map Module (Set Module) -> Module -> Set Module
reachable mapping startModule = f Set.empty startModule
where f done m = if m `Set.member` done
then done
else foldl' f (m `Set.insert` done) (get m)
get m = Set.toList (Map.findWithDefault Set.empty m mapping)
Name: dll-split
Version: 0.1
Copyright: XXX
License: BSD3
-- XXX License-File: LICENSE
Author: XXX
Maintainer: XXX
Synopsis: A tool for verifying the partitioning of the GHC library on Windows
Description:
Due to various toolchain issues (see GHC Trac #5987) we are forced to keep
DLLs on Windows smaller than 65,000 symbols. To accomplish this we split
the @ghc@ package into multiple DLLs by partitioning defined in the
build system (see @compiler/ghc.mk@).
.
This tool checks this partitioning to ensure consistency with the actual
module dependencies.
Category: Development
build-type: Simple
cabal-version: >=1.10
Executable dll-split
Default-Language: Haskell2010
Main-Is: Main.hs
Build-Depends: base >= 4 && < 5,
containers,
filepath
# -----------------------------------------------------------------------------
#
# (c) 2009 The University of Glasgow
#
# This file is part of the GHC build system.
#
# To understand how the build system works and how to modify it, see
# http://ghc.haskell.org/trac/ghc/wiki/Building/Architecture
# http://ghc.haskell.org/trac/ghc/wiki/Building/Modifying
#
# -----------------------------------------------------------------------------
utils/dll-split_USES_CABAL = YES
utils/dll-split_PACKAGE = dll-split
utils/dll-split_dist-install_PROGNAME = dll-split
utils/dll-split_dist-install_INSTALL = NO
utils/dll-split_dist-install_INSTALL_INPLACE = YES
# Use the stage0 instead of the stage1 compiler to build dll-split, to
# prevent: "dll-split: cannot execute binary file: Exec format error".
# Programs built with the stage1 compiler can only run on TARGET
# architecture, whereas dll-split is used during the GHC build process (see
# rules/build-package-way.mk) on the BUILD (=HOST) architectue.
$(eval $(call build-prog,utils/dll-split,dist-install,0))
......@@ -8,7 +8,6 @@ import Distribution.PackageDescription.Check hiding (doesFileExist)
import Distribution.PackageDescription.Configuration
import Distribution.PackageDescription.Parse
import Distribution.Package
import Distribution.System
import Distribution.Simple
import Distribution.Simple.Configure
import Distribution.Simple.LocalBuildInfo
......@@ -57,8 +56,8 @@ main = do hSetBuffering stdout LineBuffering
doRegister dir distDir ghc ghcpkg topdir
myDestDir myPrefix myLibdir myDocdir
relocatableBuild args'
"configure" : dir : distDir : dll0Modules : config_args ->
generate dir distDir dll0Modules config_args
"configure" : dir : distDir : config_args ->
generate dir distDir config_args
"sdist" : dir : distDir : [] ->
doSdist dir distDir
["--version"] ->
......@@ -67,7 +66,7 @@ main = do hSetBuffering stdout LineBuffering
syntax_error :: [String]
syntax_error =
["syntax: ghc-cabal configure <directory> <distdir> <dll0modules> <args>...",
["syntax: ghc-cabal configure <directory> <distdir> <args>...",
" ghc-cabal copy <directory> <distdir> <strip> <destdir> <prefix> <libdir> <docdir> <libways> <args>...",
" ghc-cabal register <directory> <distdir> <ghc> <ghcpkg> <topdir> <destdir> <prefix> <libdir> <docdir> <relocatable> <args>...",
" ghc-cabal hscolour <directory> <distdir> <args>...",
......@@ -265,28 +264,8 @@ updateInstallDirTemplates relocatableBuild myPrefix myLibdir myDocdir idts
htmldir = toPathTemplate "$docdir"
}
-- On Windows we need to split the ghc package into 2 pieces, or the
-- DLL that it makes contains too many symbols (#5987). There are
-- therefore 2 libraries, not just the 1 that Cabal assumes.
mangleIPI :: FilePath -> FilePath -> LocalBuildInfo
-> Installed.InstalledPackageInfo -> Installed.InstalledPackageInfo
mangleIPI "compiler" "stage2" lbi ipi
| isWindows =
-- Cabal currently only ever installs ONE Haskell library, c.f.
-- the code in Cabal.Distribution.Simple.Register. If it
-- ever starts installing more we'll have to find the
-- library that's too big and split that.
let [old_hslib] = Installed.hsLibraries ipi
in ipi {
Installed.hsLibraries = [old_hslib, old_hslib ++ "-0"]
}
where isWindows = case hostPlatform lbi of
Platform _ Windows -> True
_ -> False
mangleIPI _ _ _ ipi = ipi
generate :: FilePath -> FilePath -> String -> [String] -> IO ()
generate directory distdir dll0Modules config_args
generate :: FilePath -> FilePath -> [String] -> IO ()
generate directory distdir config_args
= withCurrentDirectory directory
$ do let verbosity = normal
-- XXX We shouldn't just configure with the default flags
......@@ -322,7 +301,7 @@ generate directory distdir dll0Modules config_args
let ipid = mkUnitId (display (packageId pd))
let installedPkgInfo = inplaceInstalledPackageInfo cwd distdir
pd (mkAbiHash "inplace") lib lbi clbi
final_ipi = mangleIPI directory distdir lbi $ installedPkgInfo {
final_ipi = installedPkgInfo {
Installed.installedUnitId = ipid,
Installed.compatPackageKey = display (packageId pd),
Installed.haddockHTMLs = []
......@@ -408,7 +387,6 @@ generate directory distdir dll0Modules config_args
let variablePrefix = directory ++ '_':distdir
mods = map display modules
otherMods = map display (otherModules bi)
allMods = mods ++ otherMods
let xs = [variablePrefix ++ "_VERSION = " ++ display (pkgVersion (package pd)),
-- TODO: move inside withLibLBI
variablePrefix ++ "_COMPONENT_ID = " ++ localCompatPackageKey lbi,
......@@ -458,11 +436,6 @@ generate directory distdir dll0Modules config_args
writeFileUtf8 (distdir ++ "/haddock-prologue.txt") $
if null (description pd) then synopsis pd
else description pd
unless (null dll0Modules) $
do let dll0Mods = words dll0Modules
dllMods = allMods \\ dll0Mods
dllModSets = map unwords [dll0Mods, dllMods]
writeFile (distdir ++ "/dll-split") $ unlines dllModSets
where
escape = foldr (\c xs -> if c == '#' then '\\':'#':xs else c:xs) []
wrap = mapM wrap1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment