diff --git a/compiler/GHC/Driver/Flags.hs b/compiler/GHC/Driver/Flags.hs
index 93748bbc0689cd4e115bfbc185a83ee34e367b22..a827ffe3150ea0eddaddc1504ffa575266a4affd 100644
--- a/compiler/GHC/Driver/Flags.hs
+++ b/compiler/GHC/Driver/Flags.hs
@@ -274,6 +274,7 @@ data GeneralFlag
    | Opt_KeepCAFs
    | Opt_KeepGoing
    | Opt_ByteCode
+   | Opt_LinkRts
 
    -- output style opts
    | Opt_ErrorSpans -- Include full span info in error messages,
diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs
index 15cce2f11d200a62c321bad3f9ff30a7e923f045..83e637401e28888cf17006d5462c9aa68b988b84 100644
--- a/compiler/GHC/Driver/Pipeline.hs
+++ b/compiler/GHC/Driver/Pipeline.hs
@@ -1937,7 +1937,14 @@ linkStaticLib dflags o_files dep_units = do
   output_exists <- doesFileExist full_output_fn
   (when output_exists) $ removeFile full_output_fn
 
-  pkg_cfgs <- getPreloadUnitsAnd dflags dep_units
+  pkg_cfgs_init <- getPreloadUnitsAnd dflags dep_units
+
+  let pkg_cfgs
+        | gopt Opt_LinkRts dflags
+        = pkg_cfgs_init
+        | otherwise
+        = filter ((/= rtsUnitId) . unitId) pkg_cfgs_init
+
   archives <- concatMapM (collectArchives dflags) pkg_cfgs
 
   ar <- foldl mappend
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs
index 85eca17aed1703ba352d359ad46adcb40a7560f1..a558ceae96bdbdef91b6f70226215b75bb30a47a 100644
--- a/compiler/GHC/Driver/Session.hs
+++ b/compiler/GHC/Driver/Session.hs
@@ -2435,7 +2435,7 @@ dynamic_flags_deps = [
   , make_ord_flag defGhcFlag "shared"
         (noArg (\d -> d { ghcLink=LinkDynLib }))
   , make_ord_flag defGhcFlag "staticlib"
-        (noArg (\d -> d { ghcLink=LinkStaticLib }))
+        (noArg (\d -> setGeneralFlag' Opt_LinkRts (d { ghcLink=LinkStaticLib })))
   , make_ord_flag defGhcFlag "dynload"            (hasArg parseDynLibLoaderMode)
   , make_ord_flag defGhcFlag "dylib-install-name" (hasArg setDylibInstallName)
 
@@ -3599,7 +3599,8 @@ fFlagsDeps = [
   flagSpec "hide-source-paths"                Opt_HideSourcePaths,
   flagSpec "show-loaded-modules"              Opt_ShowLoadedModules,
   flagSpec "whole-archive-hs-libs"            Opt_WholeArchiveHsLibs,
-  flagSpec "keep-cafs"                        Opt_KeepCAFs
+  flagSpec "keep-cafs"                        Opt_KeepCAFs,
+  flagSpec "link-rts"                         Opt_LinkRts
   ]
   ++ fHoleFlags
 
diff --git a/compiler/GHC/SysTools.hs b/compiler/GHC/SysTools.hs
index ab83b3bf2a94ee6e2a33a8eba1fb79a35275d465..0b71e8ccdebf58dce2729c8230fe072a68562b4f 100644
--- a/compiler/GHC/SysTools.hs
+++ b/compiler/GHC/SysTools.hs
@@ -274,7 +274,9 @@ linkDynLib dflags0 o_files dep_packages
         pkgs_no_rts = case os of
                       OSMinGW32 ->
                           pkgs
-                      _ ->
+                      _ | gopt Opt_LinkRts dflags ->
+                          pkgs
+                        | otherwise ->
                           filter ((/= rtsUnitId) . unitId) pkgs
     let pkg_link_opts = let (package_hs_libs, extra_libs, other_flags) = collectLinkOpts dflags pkgs_no_rts
                         in  package_hs_libs ++ extra_libs ++ other_flags
diff --git a/docs/users_guide/8.12.1-notes.rst b/docs/users_guide/8.12.1-notes.rst
index 1eb577c36e7a82a30ce295587752ec87b4c4d00b..b7f0444d6989fb85aa273f2065e9d406e493e71c 100644
--- a/docs/users_guide/8.12.1-notes.rst
+++ b/docs/users_guide/8.12.1-notes.rst
@@ -216,6 +216,9 @@ Language
 Compiler
 ~~~~~~~~
 
+- A new flag :ghc-flag:`-flink-rts` to enable linking the RTS when linking
+  shared libraries.
+
 
 GHCi
 ~~~~
diff --git a/docs/users_guide/phases.rst b/docs/users_guide/phases.rst
index 5975962370d1790742f40e91b9184249ba68283d..c7a17f6475bc4376592202dc18bb819e6e00d2cf 100644
--- a/docs/users_guide/phases.rst
+++ b/docs/users_guide/phases.rst
@@ -735,6 +735,8 @@ for example).
     :type: dynamic
     :category: linking
 
+    :implies: :ghc-flag:`-flink-rts`
+
     Link all passed files into a static library suitable for linking.
     To control the name, use the :ghc-flag:`-o ⟨file⟩` option
     as usual. The default name is ``liba.a``.
@@ -826,6 +828,23 @@ for example).
     libraries at runtime. See :ref:`finding-shared-libs` for a
     description of each mode.
 
+.. ghc-flag:: -flink-rts
+    :shortdesc: Link the runtime when generating a shared or static library
+    :type: dynamic
+    :category: linking
+
+    When linking shared libraries (:ghc-flag:`-shared`) GHC does not
+    automatically link the RTS.  This is to allow choosing the RTS flavour
+    (:ghc-flag:`-threaded`, :ghc-flag:`-eventlog`, etc) when linking an
+    executable. 
+    However when the shared library is the intended product it is useful to be
+    able to reverse this default. See :ref:`shared-libraries-c-api` for an
+    usage example.
+
+    When linking a static library (:ghc-flag:`-staticlib`) GHC links the RTS
+    automatically, you can reverse this behaviour by reversing this flag:
+    ``-fno-link-rts``.
+
 .. ghc-flag:: -main-is ⟨thing⟩
     :shortdesc: Set main module and function
     :type: dynamic
diff --git a/docs/users_guide/shared_libs.rst b/docs/users_guide/shared_libs.rst
index 7e525019ca373fdf82f43297c2545238b8321eea..4c9ad621f7cb07df2d5cf8b8ee6abcdd4450b971 100644
--- a/docs/users_guide/shared_libs.rst
+++ b/docs/users_guide/shared_libs.rst
@@ -92,6 +92,8 @@ files to use the extension ``.dyn_hi``. The other requirements are the
 same as for C libraries and are described below, in particular the use
 of the flags :ghc-flag:`-dynamic`, :ghc-flag:`-fPIC` and :ghc-flag:`-shared`.
 
+.. _shared-libraries-c-api:
+
 Shared libraries that export a C API
 ------------------------------------
 
@@ -115,19 +117,24 @@ the :ghc-flag:`-dynamic`, :ghc-flag:`-fPIC` and :ghc-flag:`-shared` flags:
 
 .. code-block:: none
 
-    ghc --make -dynamic -shared -fPIC Foo.hs -o libfoo.so
+    ghc --make -dynamic -shared -fPIC -flink-rts Foo.hs -o libfoo.so
 
 As before, the :ghc-flag:`-dynamic` flag specifies that this library links
-against the shared library versions of the ``rts`` and ``base`` package. The
-:ghc-flag:`-fPIC` flag is required for all code that will end up in a shared
-library. The :ghc-flag:`-shared` flag specifies to make a shared library rather
-than a program. To make this clearer we can break this down into separate
-compilation and link steps:
+against the shared library versions of the ``base`` package.
+:ghc-flag:`-flink-rts` additionally links against the shared library version of
+the ``rts`` package (linking against the ``rts`` package is not enabled by
+default when building shared libraries). You may also omit ``-flink-rts``
+and link the RTS library into your final executable.
+
+The :ghc-flag:`-fPIC` flag is required for all code that will end up in a
+shared library. The :ghc-flag:`-shared` flag specifies to make a shared library
+rather than a program. To make this clearer we can break this down into
+separate compilation and link steps:
 
 .. code-block:: none
 
     ghc -dynamic -fPIC -c Foo.hs
-    ghc -dynamic -shared Foo.o -o libfoo.so
+    ghc -dynamic -shared -flink-rts Foo.o -o libfoo.so
 
 In principle you can use :ghc-flag:`-shared` without :ghc-flag:`-dynamic` in the
 link step. That means to statically link the runtime system and all of the base
diff --git a/testsuite/tests/dynlibs/Makefile b/testsuite/tests/dynlibs/Makefile
index 2a530a5aebf82906617bbbfe01fd6a43b34c2f1c..19009605eac7d61f342040b7f99efef74070b561 100644
--- a/testsuite/tests/dynlibs/Makefile
+++ b/testsuite/tests/dynlibs/Makefile
@@ -14,7 +14,7 @@ T3807:
 	# libraries. This is done to allow the RTS flavour to be chosen later (i.e.
 	# when linking an executable).
 	# Hence we must explicitly linking with the RTS here.
-	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 --make -dynamic -fPIC -shared T3807Export.hs T3807-export.c -o T3807test.so -lHSrts-ghc`'$(TEST_HC)' $(TEST_HC_OPTS) --numeric-version`
+	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 --make -dynamic -fPIC -shared T3807Export.hs T3807-export.c -o T3807test.so -flink-rts
 	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -no-auto-link-packages -no-hs-main T3807-load.c -o T3807-load -ldl
 	./T3807-load
 
@@ -61,3 +61,33 @@ T5373:
 T13702:
 	'$(TEST_HC)' -v0 -dynamic -rdynamic -fPIC -pie T13702.hs
 	./T13702
+
+.PHONY: T18072
+T18072:
+	$(RM) -rf T18072/
+	mkdir T18072
+	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 -outputdir T18072 \
+    -dynamic -fPIC -c T18072.hs
+	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 -outputdir T18072 \
+    -dynamic -shared -flink-rts T18072/T18072.o -o T18072/T18072.so
+	ldd T18072/T18072.so | grep libHSrts >/dev/null
+
+.PHONY: T18072debug
+T18072debug:
+	$(RM) -rf T18072debug/
+	mkdir T18072debug
+	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 -outputdir T18072debug \
+    -dynamic -fPIC -c T18072.hs
+	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 -outputdir T18072debug \
+    -dynamic -shared -flink-rts -debug T18072debug/T18072.o -o T18072debug/T18072.so
+	ldd T18072debug/T18072.so | grep libHSrts | grep _debug >/dev/null
+
+.PHONY: T18072static
+T18072static:
+	$(RM) -rf T18072static/
+	mkdir T18072static
+	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 -outputdir T18072static \
+    -c T18072.hs
+	'$(TEST_HC)' $(filter-out -rtsopts,$(TEST_HC_OPTS)) -v0 -outputdir T18072static \
+    -staticlib -fno-link-rts T18072static/T18072.o -o T18072static/T18072.a
+	ar t T18072static/T18072.a | grep RtsSymbols.o > /dev/null && exit 1 || exit 0
diff --git a/testsuite/tests/dynlibs/T18072.hs b/testsuite/tests/dynlibs/T18072.hs
new file mode 100644
index 0000000000000000000000000000000000000000..39a174f2aef6a6ca58b5b1743bfe567366cef4ef
--- /dev/null
+++ b/testsuite/tests/dynlibs/T18072.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module T18072 where
+
+import Foreign.C
+
+foo :: IO CInt
+foo = return 3
+
+foreign export ccall foo :: IO CInt
diff --git a/testsuite/tests/dynlibs/all.T b/testsuite/tests/dynlibs/all.T
index aaa7a627747997dd5abf3086e754a286d9dd0e5c..b7272d4bac260643ecd37113d85e835208d4f92f 100644
--- a/testsuite/tests/dynlibs/all.T
+++ b/testsuite/tests/dynlibs/all.T
@@ -7,3 +7,12 @@ test('T5373', [req_shared_libs], makefile_test, [])
 
 # It's not clear exactly what platforms we can expect this to succeed on.
 test('T13702', unless(opsys('linux'), skip), makefile_test, [])
+
+# test that -shared and -flink-rts actually links the rts
+test('T18072', [req_shared_libs, unless(opsys('linux'), skip)], makefile_test, [])
+
+# test that -shared and -flink-rts respects alternative RTS flavours
+test('T18072debug', [extra_files(['T18072.hs']), req_shared_libs, unless(opsys('linux'), skip)], makefile_test, [])
+
+# check that -staticlib and -fno-link-rts results in an archive without the RTR libary 
+test('T18072static', [extra_files(['T18072.hs']), unless(opsys('linux'), skip)], makefile_test, [])