Fix building the GHC package DLL on Windows
authorIan Lynagh <igloo@earth.li>
Sun, 10 Mar 2013 16:57:23 +0000 (17:57 +0100)
committerIan Lynagh <igloo@earth.li>
Mon, 11 Mar 2013 00:23:23 +0000 (01:23 +0100)
We now put a handful of modules in a separate DLL.
For now the list is hand-written, but we could automate it in the
future.

compiler/ghc.mk
ghc.mk
rules/build-package-way.mk

index 181aba9..0c68d6d 100644 (file)
@@ -295,14 +295,6 @@ endif
 ifeq "$(GhcWithInterpreter)" "YES"
 compiler_stage2_CONFIGURE_OPTS += --flags=ghci
 
-ifeq "$(BuildSharedLibs)" "YES"
-# There are too many symbols to make a Windows DLL for the ghc package,
-# so we don't build it the dyn way; see trac #5987
-ifneq "$(TargetOS_CPP)" "mingw32"
-compiler_stage2_CONFIGURE_OPTS += --enable-shared
-endif
-endif
-
 ifeq "$(GhcEnableTablesNextToCode) $(GhcUnregisterised)" "YES NO"
 # Should GHCI be building info tables in the TABLES_NEXT_TO_CODE style
 # or not?
@@ -403,13 +395,15 @@ compiler_stage1_SplitObjs = NO
 compiler_stage2_SplitObjs = NO
 compiler_stage3_SplitObjs = NO
 
-ifeq "$(TargetOS_CPP)" "mingw32"
-# There are too many symbols to make a Windows DLL for the ghc package,
-# so we don't build it the dyn way; see trac #5987
-compiler_stage1_EXCLUDED_WAYS := dyn
-compiler_stage2_EXCLUDED_WAYS := dyn
-compiler_stage3_EXCLUDED_WAYS := dyn
-endif
+# There are too many symbols in the ghc package for a Windows DLL.
+# We therefore need to split some of the modules off into a separate
+# DLL. This clump is at the bottom of the package:
+compiler_stage2_dll0_MODULES = DynFlags FastString DriverPhases PrelNames Panic Config Unique Name RdrName Outputable OccName Pretty BufWrite Encoding UniqFM UniqSet Binary FastMutInt Util BasicTypes Module FiniteMap StaticFlags SrcLoc NameSet CmdLineParser Bag MonadUtils Constants ErrUtils Maybes Exception
+# Then some modules higher up the tree:
+compiler_stage2_dll0_MODULES += TypeRep Type Var IdInfo Demand CoreSyn Coercion Literal DataCon CostCentre TysPrim VarEnv ListSetOps TyCon TysWiredIn Unify CoAxiom Kind VarSet ForeignCall Pair MkId CoreUtils PprCore PrimOp Id CoreFVs TcType FamInstEnv OccurAnal Digraph InstEnv Class PrelRules CoreSubst CoreUnfold MkCore HscTypes CoreArity PackageConfig IfaceSyn HsImpExp ByteCodeAsm Annotations Serialized ByteCodeItbls SMRep HsDoc StgCmmLayout ByteCodeInstr StgCmmEnv MkGraph StgCmmMonad CLabel CmmType PprCmmExpr OrdList CmmMachOp CmmExpr CmmNode CodeGen.Platform CodeGen.Platform.Arm CodeGen.Platform.NoRegs CodeGen.Platform.X86 CodeGen.Platform.X86_64 CodeGen.Platform.SPARC CodeGen.Platform.PPC CodeGen.Platform.PPC_Darwin Platform Reg StgCmmClosure CmmUtils StgCmmUtils StgSyn Cmm Hoopl.Dataflow CmmCallConv Packages RegClass UniqSupply CmmInfo StgCmmTicky StgCmmProf IfaceType NameEnv Avail OptCoercion Bitmap Stream
+
+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
 ifneq "$(filter-out 1,$(stage))" ""
diff --git a/ghc.mk b/ghc.mk
index 6d0b379..864cc30 100644 (file)
--- a/ghc.mk
+++ b/ghc.mk
@@ -887,6 +887,9 @@ install_packages: rts/package.conf.install
        $(call installLibsTo, $(RTS_INSTALL_LIBS), "$(DESTDIR)$(topdir)/rts-1.0")
        $(foreach p, $(INSTALL_DYNLIBS), \
            $(call installLibsTo, $(wildcard libraries/$p/dist-install/build/*.so libraries/$p/dist-install/build/*.dll libraries/$p/dist-install/build/*.dylib), "$(DESTDIR)$(topdir)/$p-$(libraries/$p_dist-install_VERSION)"))
+ifneq "$(compiler_stage2_dyn_LIB0)" ""
+       $(call installLibsTo, $(compiler_stage2_dyn_LIB0), "$(DESTDIR)$(topdir)/ghc-$(compiler_stage2_VERSION)")
+endif
        $(foreach p, $(INSTALL_PACKAGES),                             \
            $(call make-command,                                      \
                   "$(ghc-cabal_INPLACE)" copy                        \
index 4621482..c67e258 100644 (file)
@@ -27,6 +27,16 @@ $1_$2_$3_LIB_NAME = libHS$$($1_PACKAGE)-$$($1_$2_VERSION)$$($3_libsuf)
 $1_$2_$3_LIB = $1/$2/build/$$($1_$2_$3_LIB_NAME)
 $$($1_PACKAGE)-$$($1_$2_VERSION)_$2_$3_LIB = $$($1_$2_$3_LIB)
 
+ifeq "$3" "dyn"
+ifeq "$$(HostOS_CPP)" "mingw32"
+ifneq "$$($1_$2_dll0_HS_OBJS)" ""
+$1_$2_$3_LIB0_ROOT = HS$$($1_PACKAGE)-$$($1_$2_VERSION)-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
+endif
+
 # Note [inconsistent distdirs]
 # hack: the DEPS_LIBS mechanism assumes that the distdirs for packages
 # that depend on each other are the same, but that is not the case for
@@ -52,14 +62,12 @@ ifeq "$3" "dyn"
 # On windows we have to supply the extra libs this one links to when building it.
 ifeq "$$(HostOS_CPP)" "mingw32"
 $$($1_$2_$3_LIB) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
-       $$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) $$($1_$2_$3_GHC_LD_OPTS) $$($1_$2_$3_ALL_OBJS) \
-         -shared -dynamic -dynload deploy \
-        $$(addprefix -l,$$($1_$2_EXTRA_LIBRARIES)) \
-         -no-auto-link-packages \
-         -o $$@
-# Now check that the DLL doesn't have too many symbols. See trac #5987.
-       case `$$(OBJDUMP) -p $$@ | sed -n "1,/^.Ordinal\/Name Pointer/ D; p; /^$$$$/ q" | grep "\[ *0\]" | wc -l` in 1) echo DLL $$@ OK;; 0) echo No symbols in DLL $$@; exit 1;; [0-9]*) echo Too many symbols in DLL $$@; exit 1;; *) echo bad DLL $$@; exit 1;; esac
-
+ifneq "$$($1_$2_$3_LIB0)" ""
+       $$(call build-dll,$1,$2,$3,,$$($1_$2_dll0_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$($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
 else
 $$($1_$2_$3_LIB) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
        $$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) $$($1_$2_$3_GHC_LD_OPTS) $$($1_$2_$3_ALL_OBJS) \
@@ -93,6 +101,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)
 endif
 
 # Build the GHCi library
@@ -122,3 +131,19 @@ endif
 $(call profEnd, build-package-way($1,$2,$3))
 endef
 
+# $1 = dir
+# $2 = distdir
+# $3 = way
+# $4 = extra flags
+# $5 = object files to link
+# $6 = output filename
+define build-dll
+       $(call cmd,$1_$2_HC) $($1_$2_$3_ALL_HC_OPTS) $($1_$2_$3_GHC_LD_OPTS) $4 $5 \
+           -shared -dynamic -dynload deploy \
+           $(addprefix -l,$($1_$2_EXTRA_LIBRARIES)) \
+           -no-auto-link-packages \
+           -o $6
+# Now check that the DLL doesn't have too many symbols. See trac #5987.
+       case `$(OBJDUMP) -p $6 | sed -n "1,/^.Ordinal\/Name Pointer/ D; p; /^$$/ q" | grep "\[ *0\]" | wc -l` in 1) echo DLL $6 OK;; 0) echo No symbols in DLL $6; exit 1;; [0-9]*) echo Too many symbols in DLL $6; $(OBJDUMP) -p $6 | sed -n "1,/^.Ordinal\/Name Pointer/ D; p; /^$$/ q" | tail; exit 1;; *) echo bad DLL $6; exit 1;; esac
+endef
+