diff --git a/ghc.mk b/ghc.mk
index c9b280984a405bcdbc4bc14263479e35c6afb60d..f49ca1368617b53342861fb52a88ec6af6b39166 100644
--- a/ghc.mk
+++ b/ghc.mk
@@ -320,8 +320,11 @@ PACKAGES += haskeline
 
 BOOT_PKGS = Cabal hpc extensible-exceptions
 
-# The actual .a files: needed for dependencies.
+# The actual .a and .so/.dll files: needed for dependencies.
 ALL_LIBS  = $(foreach lib,$(PACKAGES),$(libraries/$(lib)_dist-install_v_LIB))
+ifeq "$(BuildSharedLibs)" "YES"
+ALL_LIBS += $(foreach lib,$(PACKAGES),$(libraries/$(lib)_dist-install_dyn_LIB))
+endif
 BOOT_LIBS = $(foreach lib,$(BOOT_PKGS),$(libraries/$(lib)_dist-boot_v_LIB))
 
 OTHER_LIBS = libffi/libHSffi.a libffi/HSffi.o
diff --git a/rules/build-package-data.mk b/rules/build-package-data.mk
index a260138286157ad260bd397817db78a0762c358d..2f1a83aca2f4f18fa30cd574e7ea051f88f176d0 100644
--- a/rules/build-package-data.mk
+++ b/rules/build-package-data.mk
@@ -12,6 +12,10 @@
 
 define build-package-data # args: $1 = dir, $2 = distdir
 
+ifeq "$(BuildSharedLibs)" "YES"
+$1_$2_CONFIGURE_FLAGS += --enable-shared
+endif
+
 ifeq "$(HSCOLOUR_SRCS)" "YES"
 $1_$2_CONFIGURE_FLAGS += --with-hscolour="$$(HSCOLOUR)"
 endif
diff --git a/rules/build-package-way.mk b/rules/build-package-way.mk
index 5fb3cdf9ee338d5b8136a3aa09f7efa11e769bd2..41496db9154b4d4452c822f30048660e663c95b5 100644
--- a/rules/build-package-way.mk
+++ b/rules/build-package-way.mk
@@ -26,6 +26,16 @@ $1_$2_$3_MKSTUBOBJS = find $1/$2/build -name "*_stub.$$($3_osuf)" -print
 # HACK ^^^ we tried to use $(wildcard), but apparently it fails due to
 # make using cached directory contents, or something.
 
+ifeq "$3" "dyn"
+# Link a dynamic library
+$$($1_$2_$3_LIB) : $$($1_$2_$3_HS_OBJS) $$($1_$2_dyn_C_OBJS) $$($1_$2_dyn_S_OBJS) $$(ALL_RTS_LIBS)
+	$$(RM) $$@
+	$$($1_$2_HC) $$($1_$2_dyn_C_OBJS) $$($1_$2_dyn_S_OBJS) $$($1_$2_$3_HS_OBJS) \
+         `$$($1_$2_$3_MKSTUBOBJS)` \
+         -shared -dynamic \
+         -no-auto-link-packages $$(addprefix -package,$$($1_$2_DEPS)) \
+         -o $$@
+else
 # Build the ordinary .a library
 ifeq "$$($1_$2_SplitObjs)" "YES"
 $$($1_$2_$3_LIB) : $$($1_$2_$3_HS_OBJS) $$($1_$2_v_C_OBJS) $$($1_$2_v_S_OBJS)
@@ -36,6 +46,7 @@ $$($1_$2_$3_LIB) : $$($1_$2_$3_HS_OBJS) $$($1_$2_v_C_OBJS) $$($1_$2_v_S_OBJS)
 	$$(RM) $$@
 	echo $$($1_$2_v_C_OBJS) $$($1_$2_v_S_OBJS) $$($1_$2_$3_HS_OBJS) `$$($1_$2_$3_MKSTUBOBJS)` | xargs $$(AR) $$(EXTRA_AR_ARGS) $$@
 endif
+endif
 
 $(call all-target,$1_$2,all_$1_$2_$3)
 $(call all-target,$1_$2_$3,$$($1_$2_$3_LIB))
diff --git a/rules/build-package.mk b/rules/build-package.mk
index 863dc73f2d317e5375229444bd73d49ceba657c1..fb7d9d230cf497a443d0fe3c68205b1fb19aa6f2 100644
--- a/rules/build-package.mk
+++ b/rules/build-package.mk
@@ -28,8 +28,6 @@
 # libraries/base_dist_CC_OPTS = -Iinclude ...
 # libraries/base_dist_LD_OPTS = -package ghc-prim-0.1.0.0
 
-# TODO: soext
-
 define build-package
 # $1 = dir
 # $2 = distdir
@@ -123,10 +121,14 @@ $1_$2_SplitObjs = NO
 endif
 endif
 
-# C and S files are built the "v" vanlilla way
+# C and S files are built the "v" vanlilla way and possibly also the "dyn" way.
 $(call c-objs,$1,$2,v)
 $(call distdir-opts,$1,$2,$3)
 $(call c-suffix-rules,$1,$2,v,YES)
+ifeq "$(BuildSharedLibs)" "YES"
+$(call c-objs,$1,$2,dyn)
+$(call c-suffix-rules,$1,$2,dyn,YES)
+endif
 
 # Now generate all the build rules for each way in this directory:
 $$(foreach way,$$($1_$2_WAYS),$$(eval $$(call build-package-way,$1,$2,$$(way),$3)))