diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml
--- a/.github/workflows/haskell.yml
+++ b/.github/workflows/haskell.yml
@@ -1,9 +1,9 @@
 name: Haskell CI
 on:
   push:
-    branches: [main, master]
+    branches: [ master ]
   pull_request:
-    branches: [main, master]
+    branches: [ master ]
 
 permissions:
   contents: read
@@ -23,10 +23,12 @@
           , "9.6"
           , "9.8"
           , "9.10"
+          , "9.12"
+          , "latest"
           ]
 
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
         with:
           submodules: 'recursive'
 
@@ -44,13 +46,12 @@
 
       - name: Configure the build
         run: |
-          # (2024-10-11) doctests are failing only with ghc-9.2 on github CI
-          cabal configure --enable-tests --enable-benchmarks --disable-documentation --flag=pedantic --flag=-doctests
+          cabal configure --enable-tests --enable-benchmarks --disable-documentation --flag=pedantic
           cabal build --dry-run
         # The last step generates dist-newstyle/cache/plan.json for the cache key.
 
       - name: Restore cached dependencies
-        uses: actions/cache/restore@v3
+        uses: actions/cache/restore@v4
         id: cache
         env:
           key: ${{ runner.os }}-ghc-${{ steps.setup.outputs.ghc-version }}-cabal-${{ steps.setup.outputs.cabal-version }}
@@ -60,13 +61,15 @@
           restore-keys: ${{ env.key }}-
 
       - name: Install dependencies
+        # If we had an exact cache hit, the dependencies will be up to date.
+        if: steps.cache.outputs.cache-hit != 'true'
         run: cabal build all --only-dependencies
 
       # Cache dependencies already here, so that we do not have to rebuild them should the subsequent steps fail.
       - name: Save cached dependencies
-        uses: actions/cache/save@v3
-        # Caches are immutable, trying to save with the same key would error.
-        if: ${{ steps.cache.outputs.cache-primary-key != steps.cache.outputs.cache-matched-key }}
+        uses: actions/cache/save@v4
+        # If we had an exact cache hit, trying to save the cache would error because of key clash.
+        if: steps.cache.outputs.cache-hit != 'true'
         with:
           path: ${{ steps.setup.outputs.cabal-store }}
           key: ${{ steps.cache.outputs.cache-primary-key }}
@@ -78,4 +81,8 @@
         run: cabal test all --test-option=--color --test-show-details=streaming --jobs=1
 
       - name: Build documentation
-        run: cabal haddock all
+        run:
+          cabal haddock all --disable-documentation
+          # --disable-documentation disables building documentation for dependencies.
+          # The package's own documentation is still built,
+          # yet contains no links to the documentation of the dependencies.
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,27 @@
+## v0.9.1.0 (2025-05-02)
+
+Release v0.9.1.0
+
+- Add library versions for ghc-9.6.7, ghc-9.12.1 and ghc-9.12.2
+
+- Fix <https://github.com/gentoo-haskell/hackport/issues/134>
+
+- Test with ghc-9.12 in GitHub CI
+
+- Add support for "#hackport: external-depends: ..."
+
+  This is intended for situations where a Haskell package depends on a
+  non-Haskell executable (which does not have a canonical field in the
+  .cabal file spec).
+
+  Does not currently support flags or version ranges on the atoms. Does
+  not support BDEPEND yet as this needs to be added to
+  `Merge.Dependencies.EDep` (see <https://github.com/gentoo-haskell/hackport/issues/130>).
+
+  Random example:
+
+      #hackport: external-depends: rdepend:dev-db/postgresql,depend:app-misc/ca-certificates
+
 ## v0.9.0.0 (2024-12-02)
 
 Release v0.9.0.0
diff --git a/hackport.cabal b/hackport.cabal
--- a/hackport.cabal
+++ b/hackport.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name:          hackport
-version:       0.9.0.0
+version:       0.9.1.0
 license:       GPL-3.0-or-later
 license-file:  LICENSE
 author:        Henning Günther, Duncan Coutts, Lennart Kolmodin
@@ -29,7 +29,7 @@
 
 source-repository head
   type:     git
-  location: git://github.com/gentoo-haskell/hackport.git
+  location: https://github.com/gentoo-haskell/hackport.git
 
 flag cabal-v1
   description: Build for cabal-v1 (Setup.hs/gentoo-haskell) compatibility
@@ -61,6 +61,13 @@
   default:     True
   manual:      True
 
+-- Needed to build hackport in "offline" (gentoo-only) mode
+-- See: <https://github.com/gentoo-haskell/gentoo-haskell/issues/1074>
+flag build-tool-depends
+  description: Enable dependencies via build-tool-depends
+  default:     True
+  manual:      True
+
 -- Turn off all warnings (for external libs and doctests-v2)
 common no-warnings
   ghc-options: -Wno-default -Wno-incomplete-uni-patterns
@@ -1069,9 +1076,14 @@
     , base <5
     , process
 
-  build-tool-depends:
-    -- cabal-install should already be installed if this is being built...
-    , doctest:doctest      >=0.8
+  if flag(build-tool-depends)
+    build-tool-depends:
+      -- cabal-install should already be installed if this is being built...
+      , doctest:doctest      >=0.8
+  else
+    build-depends:
+      directory
+    cpp-options: -DEXTERNAL_DOCTEST
 
   if !flag(doctests) || flag(cabal-v1)
     buildable: False
@@ -1119,5 +1131,7 @@
     , time
     , xml
 
-  build-tool-depends: hspec-discover:hspec-discover >=2.0
   other-extensions:   DeriveDataTypeable
+
+  if flag(build-tool-depends)
+    build-tool-depends: hspec-discover:hspec-discover >=2.0
diff --git a/src/Error.hs b/src/Error.hs
--- a/src/Error.hs
+++ b/src/Error.hs
@@ -7,7 +7,6 @@
     , catch
     ) where
 
-import Data.Typeable
 import Control.Exception
 
 -- | Type holding all of the 'HackPortError' constructors.
@@ -32,8 +31,8 @@
     -- | WrongCacheVersion
     -- | InvalidCache
     | InvalidServer String
-    deriving (Typeable
-             , Show
+    deriving (
+             Show
              , Eq -- ^ needed for spec test-suite
              )
 
diff --git a/src/Merge.hs b/src/Merge.hs
--- a/src/Merge.hs
+++ b/src/Merge.hs
@@ -368,9 +368,17 @@
                         (d1:d2:ds) -> go (mappend d1 d2 : go ds)
                         _          -> deps'
 
-      tdeps :: Merge.EDep
-      tdeps = bimerge $ map set_fa_to_ed deps1'
+      addExternalDepends :: EM.EMeta -> Merge.EDep -> Env env Merge.EDep
+      addExternalDepends emeta deps0 = case EM.externalDepends emeta of
+          Nothing -> pure deps0
+          Just eDepStr -> case EM.parseExternalDepends eDepStr of
+              Left s -> deps0 <$ warn ("external-depends: " ++ s)
+              Right d -> pure $ deps0 <> d
 
+      getTdeps :: Env env Merge.EDep
+      getTdeps = bimerge
+          <$> traverse (addExternalDepends existing_meta . set_fa_to_ed) deps1'
+
       set_fa_to_ed :: (CabalFlags, Merge.EDep) -> Merge.EDep
       set_fa_to_ed (fa, ed) = ed { Merge.rdep = liftFlags (leave_only_dynamic_fa fa) $ Merge.rdep ed
                                  , Merge.dep  = liftFlags (leave_only_dynamic_fa fa) $ Merge.dep ed
@@ -425,6 +433,8 @@
           Just [] -> die "No output from 'portageq envvar ARCH'"
           Just (l:_) -> pure l
 
+  tdeps <- getTdeps
+
   let pp_fn (cabal_fn, yesno) = b yesno ++ Cabal.unFlagName cabal_fn
           where b True  = ""
                 b False = "-"
@@ -454,9 +464,12 @@
                   in p ++ cfn_to_iuse fn
 
       ebuild =   (\e -> e { E.iuse = E.iuse e ++ map to_iuse active_flag_descs })
-               . ( case requested_cabal_flags of
-                       Nothing  -> id
-                       Just ucf -> (\e -> e { E.used_options  = E.used_options e ++ [("flags", ucf)] }))
+               . ( \e -> e { E.used_options
+                           = maybe id (\ds -> (++ [("external-depends", ds)]))
+                                 (EM.externalDepends existing_meta)
+                           $ maybe id (\ucf -> (++ [("flags",ucf)]))
+                                 requested_cabal_flags
+                           $ E.used_options e } )
                $ (C2E.cabal2ebuild cat (Merge.packageDescription pkgDesc))
                   { E.depend        =            Merge.dep tdeps
                   , E.depend_extra  = S.toList $ Merge.dep_e tdeps
diff --git a/src/Merge/Dependencies.hs b/src/Merge/Dependencies.hs
--- a/src/Merge/Dependencies.hs
+++ b/src/Merge/Dependencies.hs
@@ -315,7 +315,7 @@
       , ("sqlite3", at_least_c_p_v "dev-db" "sqlite" [3,0])
       , ("stdc++", Portage.DependAnyOf
             [ any_c_p_s_u "sys-devel" "gcc" Portage.AnySlot [Portage.mkUse (Portage.Use "cxx")]
-            , any_c_p "sys-devel" "clang"
+            , any_c_p "llvm-core" "clang"
             ])
       , ("crack", any_c_p "sys-libs" "cracklib")
       , ("exif", any_c_p "media-libs" "libexif")
@@ -430,7 +430,7 @@
   , ("gtk2hsC2hs",          any_c_p "dev-haskell" "gtk2hs-buildtools")
   , ("hsb2hs",              any_c_p "dev-haskell" "hsb2hs")
   , ("hsx2hs",              any_c_p "dev-haskell" "hsx2hs")
-  , ("llvm-config",         any_c_p "sys-devel" "llvm")
+  , ("llvm-config",         any_c_p "llvm-core" "llvm")
   ]
 
 -- tools that are provided by ghc or some other existing program
@@ -446,7 +446,8 @@
 hackageBuildToolsDependencies overlay (Cabal.PackageDescription { Cabal.library = lib, Cabal.executables = exes }) =
   haskellDependencies overlay $ L.nub $
     [ Cabal.Dependency pn versionRange $ NES.singleton Cabal.defaultLibName
-    | Cabal.ExeDependency pn _component versionRange <- cabalDeps
+    | Cabal.ExeDependency pn _component versionRange <- cabalDeps,
+      not (any (== Cabal.unPackageName pn) buildToolsProvided) -- ignore provided tools
     ]
   where
     cabalDeps = depL ++ depE
@@ -617,4 +618,14 @@
   ,("dbusmenu-glib-0.4",           ("dev-libs", "libdbusmenu", Portage.DAttr Portage.AnySlot [Portage.mkUse $ Portage.Use "introspection"]))
   ,("dbusmenu-gtk3-0.4",           ("dev-libs", "libdbusmenu", Portage.DAttr Portage.AnySlot
     (Portage.mkUse <$> [Portage.Use "gtk3", Portage.Use "introspection"])))
+  ,("gpgme",                       ("app-crypt", "gpgme", def))
+  ,("mp3lame",                     ("media-sound", "lame", def))
+  ,("samplerate",                  ("media-libs", "libsamplerate", def))
+  ,("libavcodec",                  ("media-video", "ffmpeg", def))
+  ,("libavdevice",                 ("media-video", "ffmpeg", def))
+  ,("libavformat",                 ("media-video", "ffmpeg", def))
+  ,("libavutil",                   ("media-video", "ffmpeg", def))
+  ,("libswresample",               ("media-video", "ffmpeg", def))
+  ,("libswscal",                   ("media-video", "ffmpeg", def))
+  ,("FLAC",                        ("media-libs", "flac", def))
   ]
diff --git a/src/Portage/EMeta.hs b/src/Portage/EMeta.hs
--- a/src/Portage/EMeta.hs
+++ b/src/Portage/EMeta.hs
@@ -10,17 +10,24 @@
 module Portage.EMeta
   ( EMeta(..)
   , findExistingMeta
+  , parseExternalDepends
   ) where
 
 import Control.Monad
 import Control.Monad.IO.Class
 import Data.Char (isSpace)
 import qualified Data.List as L
-
+import qualified Data.Monoid as Monoid
 import System.Directory (doesDirectoryExist, getDirectoryContents)
 import System.FilePath ((</>))
 import Text.Printf
 
+import qualified Distribution.Parsec as Cabal
+
+import qualified Merge.Dependencies as Merge
+import qualified Portage.Dependency.Types as Portage
+import qualified Portage.PackageId as Portage
+
 -- | Extract a value of variable in \'var=\"val\"\' format.
 -- There should be exactly one variable assignment in the ebuild.
 -- It's a bit of an artificial limitation, but it's common for \'if / else\' blocks.
@@ -76,12 +83,65 @@
 extractDescription ebuild_path s_ebuild =
     extract_quoted_string ebuild_path s_ebuild "DESCRIPTION"
 
+-- | Extract information on external dependencies that cannot be specified in
+--   the .cabal file.
+extractExternalDepends :: FilePath -> String -> Maybe String
+extractExternalDepends ebuild_path s_ebuild =
+    extract_hackport_var ebuild_path s_ebuild "external-depends"
+
+-- | Parse @external-depends@ string from ebulds. These can be added to an
+--   existing 'Merge.EDep' using its 'Semigroup' instance.
+--
+--   Example of valid input:
+--
+--   @@@
+--   "rdepend:app-misc/foo,depend:app-misc/bar"
+--   @@@
+--
+--   NOTE: This does not currently support flags or version ranges on the atoms
+
+parseExternalDepends :: String -> Either String Merge.EDep
+parseExternalDepends
+    = Monoid.getAp
+    . foldMap parseEntry
+    . finalizeSplit
+    . foldr splitOnCommas ([],"")
+  where
+    finalizeSplit :: ([String], String) -> [String]
+    finalizeSplit (results,"") = results
+    finalizeSplit (results,working) = results ++ [working]
+
+    splitOnCommas :: Char -> ([String],String) -> ([String], String)
+    splitOnCommas ',' (results,working) = (results ++ [working], "")
+    splitOnCommas  c  (results,working) = (results, c : working)
+
+    parseEntry :: String -> Monoid.Ap (Either String) Merge.EDep
+    parseEntry s0 = Monoid.Ap $ case L.span (/= ':') s0 of
+        (ls, ':' : rs) -> do
+
+            pkg@(Portage.PackageName _ _) <- Cabal.eitherParsec rs
+
+            let drange = Portage.DRange Portage.ZeroB Portage.InfinityB
+                dattr = Portage.DAttr Portage.AnySlot []
+                atom = Portage.Atom pkg drange dattr
+
+            f <- case ls of
+                "rdepend" -> Right $ \a p -> p { Merge.rdep = a }
+                "depend" -> Right $ \a p -> p { Merge.dep = a }
+                s -> Left $ "could not parse dependency class: " ++ show s
+
+            pure $ f (Portage.DependAtom atom) mempty
+
+        _ -> Left $ "could not parse entry: " ++ show s0
+
+
 -- | Type representing the aggregated (best inferred) metadata for a
 -- new ebuild of a package.
 data EMeta = EMeta { keywords :: Maybe [String]
                    , license  :: Maybe String
                    , cabal_flags :: Maybe String
                    , description :: Maybe String
+                   , externalDepends :: Maybe String
                    }
 
 -- | Find the existing package metadata from the last available ebuild.
@@ -101,6 +161,7 @@
             , license = extractLicense e eConts
             , cabal_flags = extractCabalFlags e eConts
             , description = extractDescription e eConts
+            , externalDepends = extractExternalDepends e eConts
             }
     let get_latest candidates = last (Nothing : filter (/= Nothing) candidates)
         aggregated_meta = EMeta
@@ -108,5 +169,6 @@
             , license = get_latest $ map license eMetas
             , cabal_flags = get_latest $ map cabal_flags eMetas
             , description = get_latest $ map description eMetas
+            , externalDepends = get_latest $ map externalDepends eMetas
             }
     pure aggregated_meta
diff --git a/src/Portage/GHCCore.hs b/src/Portage/GHCCore.hs
--- a/src/Portage/GHCCore.hs
+++ b/src/Portage/GHCCore.hs
@@ -35,6 +35,7 @@
 
 import Data.Maybe
 import Data.List ( nub )
+import qualified Data.Set as S
 
 import Debug.Trace
 
@@ -45,9 +46,10 @@
     [ ghc902
     , ghc924, ghc925, ghc926, ghc927, ghc928
     , ghc945, ghc946, ghc947, ghc948
-    , ghc962, ghc963, ghc964, ghc965, ghc966
+    , ghc962, ghc963, ghc964, ghc965, ghc966, ghc967
     , ghc982, ghc983, ghc984
     , ghc9101
+    , ghc9121, ghc9122
     ]
 
 -- | Maybe determine the appropriate 'Cabal.Version' of the @Cabal@ package
@@ -74,10 +76,13 @@
           , ([9,6,4], Cabal.mkVersion [3,10,1,0])
           , ([9,6,5], Cabal.mkVersion [3,10,3,0])
           , ([9,6,6], Cabal.mkVersion [3,10,3,0])
+          , ([9,6,7], Cabal.mkVersion [3,10,3,0])
           , ([9,8,2], Cabal.mkVersion [3,10,3,0]) -- bumped via BUMP_LIBRARIES
           , ([9,8,3], Cabal.mkVersion [3,10,3,0])
           , ([9,8,4], Cabal.mkVersion [3,10,3,0])
           , ([9,10,1], Cabal.mkVersion [3,12,0,0])
+          , ([9,12,1], Cabal.mkVersion [3,14,1,1]) -- bumped via BUMP_LIBRARIES
+          , ([9,12,2], Cabal.mkVersion [3,14,1,1]) -- bumped via BUMP_LIBRARIES
           ]
 
 platform :: Platform
@@ -150,7 +155,10 @@
 --
 -- This takes the version of GHC as the first parameter, and uses it to
 -- automatically add @ghc-boot@, @ghc-boot-th@, @ghc-heap@, and @ghci@ (all of
--- which share the same version number as GHC).
+-- which share the same version number as GHC). In addition, it generates
+-- what seems to be standard versioning for @ghc-experimental@ and @ghc-internal@.
+-- A Default library number will only be applied if it is not already present
+-- in @pids@.
 mkIndex :: [Int] -> [Cabal.PackageIdentifier] -> InstalledPackageIndex
 mkIndex ghcVer pids = fromList
       [ emptyInstalledPackageInfo
@@ -159,40 +167,57 @@
           }
       | pindex@(Cabal.PackageIdentifier _name _version) <- pids' ]
   where
-    pids' =
-        p "ghc-boot" ghcVer
-      : p "ghc-boot-th" ghcVer
-      : p "ghc-heap" ghcVer
-      : p "ghci" ghcVer
-      : filter filtUpgradeable pids
+    pids' = S.toAscList $ S.union
+      ( S.fromList (filter filtUpgradeable pids) )
+      -- These defaults will be ignored if they are already defined in 'pids'
+      ( S.fromList
+          [ p "ghc-boot" ghcVer
+          , p "ghc-boot-th" ghcVer
+          , p "ghc-heap" ghcVer
+          , p "ghci" ghcVer
+          , ghcExp "ghc-experimental" ghcVer
+          , ghcExp "ghc-internal" ghcVer
+          ] )
 
     -- | only include 'Cabal.PackageIdentifier's whose 'Cabal.packageName' does
     --   not match anything from 'upgradeablePkgs'
     filtUpgradeable :: Cabal.PackageIdentifier -> Bool
     filtUpgradeable pid =
-        all (Cabal.packageName pid /=) (upgradeablePkgs ghcVer)
+        all (Cabal.packageName pid /=) upgradeablePkgs
 
+    -- e.g. foo-9.1201.0 from: ghcExp "foo" [9,12,1]
+    ghcExp :: String -> [Int] -> Cabal.PackageIdentifier
+    ghcExp s (v:vs) = p s [v, read (concat (map pad vs)), 0]
+        where pad i | i < 10 = "0" ++ show i
+                    | otherwise = show i
+    ghcExp s _ = p s [0]
+
 -- | These bundled packages are "upgradeable" and should not be present in the
 --   generated 'InstalledPackageIndex'. If they are, they will /not/ show up
 --   in the generated list of dependencies (@RDEPEND@ and/or @DEPEND@), which
 --   is undesireable (since this is where required version ranges are found).
 --
---   Takes the '[Int]' representation of the GHC version as an argument to
---   determine if any extra upgradeable packages are bundled.
---
 --   See: <https://github.com/gentoo-haskell/gentoo-haskell/issues/1386>
-upgradeablePkgs :: [Int] -> [Cabal.PackageName]
-upgradeablePkgs ghcVer
-    -- Upgradeable package @Cabal-syntax@ gets bundled with >=ghc-9.4
-    | ghcVer >= [9,4] = "Cabal-syntax" : upgradeablePkgs [9,0]
-    -- These have been bundled since at least ghc-9.0
-    | otherwise =
-        [ "Cabal"
-        , "haskeline"
-        , "parsec"
-        , "text"
-        , "xhtml"
-        ]
+upgradeablePkgs :: [Cabal.PackageName]
+upgradeablePkgs =
+    [ -- Upgradeable packages bundled with >=ghc-9.12
+      "haddock-api"
+    , "haddock-library"
+      -- NOT upgradeable in ghc-9.12, but needs to be added to the ebuild for
+      -- earlier versions of ghc.
+    , "os-string"
+      -- Upgradeable packages bundled with >=ghc-9.10
+    , "ghc-platform"
+    , "ghc-toolchain"
+      -- Upgradeable packages bundled with >=ghc-9.4
+    , "Cabal-syntax"
+      -- The rest
+    , "Cabal"
+    , "haskeline"
+    , "parsec"
+    , "text"
+    , "xhtml"
+    ]
 
 
 packageNamesFromPackageIndex :: InstalledPackageIndex -> [Cabal.PackageName]
@@ -209,6 +234,12 @@
   -> (DC.CompilerInfo, InstalledPackageIndex)
 mkInfoIndex ghcVer pids = (ghc ghcVer, mkIndex ghcVer pids)
 
+ghc9122 :: (DC.CompilerInfo, InstalledPackageIndex)
+ghc9122 = mkInfoIndex [9,12,2] ghc9122_pkgs
+
+ghc9121 :: (DC.CompilerInfo, InstalledPackageIndex)
+ghc9121 = mkInfoIndex [9,12,1] ghc9121_pkgs
+
 ghc9101 :: (DC.CompilerInfo, InstalledPackageIndex)
 ghc9101 = mkInfoIndex [9,10,1] ghc9101_pkgs
 
@@ -221,6 +252,9 @@
 ghc982 :: (DC.CompilerInfo, InstalledPackageIndex)
 ghc982 = mkInfoIndex [9,8,2] ghc982_pkgs
 
+ghc967 :: (DC.CompilerInfo, InstalledPackageIndex)
+ghc967 = mkInfoIndex [9,6,7] ghc967_pkgs
+
 ghc966 :: (DC.CompilerInfo, InstalledPackageIndex)
 ghc966 = mkInfoIndex [9,6,6] ghc966_pkgs
 
@@ -278,29 +312,118 @@
 --  * https://flora.pm/packages/%40hackage/ghc/9.0.2/dependencies
 --  * https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/libraries/version-history
 --  * @./scripts/scan-ghc-library-versions.hs@ in the gentoo-haskell tree
+ghc9122_pkgs :: [Cabal.PackageIdentifier]
+ghc9122_pkgs =
+  [ p "Cabal-syntax" [3,14,1,0]
+  , p "Cabal" [3,14,1,1] -- bumped via BUMP_LIBRARIES
+  , p "array" [0,5,8,0]
+  , p "base" [4,21,0,0]
+  , p "binary" [0,8,9,3]
+  , p "bytestring" [0,12,2,0]
+  , p "containers" [0,7]
+  , p "deepseq" [1,5,1,0]
+  , p "directory" [1,3,9,0]
+  , p "exceptions" [0,10,9]
+  , p "file-io" [0,1,5]
+  , p "filepath" [1,5,4,0]
+  , p "ghc-bignum" [1,3]
+  , p "ghc-compact" [0,1,0,0]
+  , p "ghc-prim" [0,13,0]
+  , p "ghc-platform" [0,1,0,0]
+  , p "ghc-toolchain" [0,1,0,0]
+  , p "haddock-api" [2,30,0]
+  , p "haddock-library" [1,11,0]
+  , p "haskeline" [0,8,2,1]
+  , p "hpc" [0,7,0,2]
+  , p "integer-gmp" [1,1]
+  , p "mtl" [2,3,1]
+  , p "os-string" [2,0,7]
+  , p "parsec" [3,1,18,0]
+  , p "pretty" [1,1,3,6]
+  , p "process" [1,6,25,0]
+  , p "rts" [1,0,2]
+  , p "semaphore-compat" [1,0,0]
+  , p "stm" [2,5,3,1]
+  , p "template-haskell" [2,23,0,0]
+  , p "terminfo" [0,4,1,7]
+  , p "text" [2,1,2]
+  , p "time" [1,14]
+  , p "transformers" [0,6,1,2]
+  , p "unix" [2,8,6,0]
+  , p "xhtml" [3000,2,2,1]
+  ]
+
+ghc9121_pkgs :: [Cabal.PackageIdentifier]
+ghc9121_pkgs =
+  [ p "Cabal-syntax" [3,14,1,0]
+  , p "Cabal" [3,14,1,1] -- bumped via BUMP_LIBRARIES
+  , p "array" [0,5,8,0]
+  , p "base" [4,21,0,0]
+  , p "binary" [0,8,9,2]
+  , p "bytestring" [0,12,2,0]
+  , p "containers" [0,7]
+  , p "deepseq" [1,5,1,0]
+  , p "directory" [1,3,9,0]
+  , p "exceptions" [0,10,9]
+  , p "file-io" [0,1,5]
+  , p "filepath" [1,5,4,0]
+  , p "ghc-bignum" [1,3]
+  , p "ghc-compact" [0,1,0,0]
+  , p "ghc-prim" [0,13,0]
+  , p "ghc-platform" [0,1,0,0]
+  , p "ghc-toolchain" [0,1,0,0]
+  , p "haddock-api" [2,30,0]
+  , p "haddock-library" [1,11,0]
+  , p "haskeline" [0,8,2,1]
+  , p "hpc" [0,7,0,1]
+  , p "integer-gmp" [1,1]
+  , p "mtl" [2,3,1]
+  , p "os-string" [2,0,7]
+  , p "parsec" [3,1,17,0]
+  , p "pretty" [1,1,3,6]
+  , p "process" [1,6,25,0]
+  , p "rts" [1,0,2]
+  , p "semaphore-compat" [1,0,0]
+  , p "stm" [2,5,3,1]
+  , p "template-haskell" [2,23,0,0]
+  , p "terminfo" [0,4,1,6]
+  , p "text" [2,1,2]
+  , p "time" [1,14]
+  , p "transformers" [0,6,1,2]
+  , p "unix" [2,8,6,0]
+  , p "xhtml" [3000,2,2,1]
+  ]
+
 ghc9101_pkgs :: [Cabal.PackageIdentifier]
 ghc9101_pkgs =
   [ p "Cabal-syntax" [3,12,0,0]
   , p "Cabal" [3,12,0,0]
-  , p "array" [0,5,7,0]
+  , p "array" [0,5,8,0] -- bumped via BUMP_LIBRARIES
   , p "base" [4,20,0,0]
   , p "binary" [0,8,9,2]
   , p "bytestring" [0,12,1,0]
   , p "containers" [0,7]
-  , p "deepseq" [1,5,0,0]
-  , p "directory" [1,3,8,5] -- bumped via BUMP_LIBRARIES
+  , p "deepseq" [1,5,1,0] -- bumped via BUMP_LIBRARIES
+  , p "directory" [1,3,9,0] -- bumped via BUMP_LIBRARIES
   , p "exceptions" [0,10,7]
+  , p "file-io" [0,1,5] -- added via hadrian patch and BUMP_LIBRARIES
   , p "filepath" [1,5,2,0]
   , p "ghc-bignum" [1,3]
   , p "ghc-compact" [0,1,0,0]
+  , p "ghc-experimental" [0,1,0,0]
+  , p "ghc-internal" [9,1001,0]
   , p "ghc-prim" [0,11,0]
+  , p "ghc-platform" [0,1,0,0]
+  , p "ghc-toolchain" [0,1,0,0]
   , p "haskeline" [0,8,2,1]
   , p "hpc" [0,7,0,1]
   , p "integer-gmp" [1,1]
   , p "mtl" [2,3,1]
+  , p "os-string" [2,0,7] -- bumped via BUMP_LIBRARIES
   , p "parsec" [3,1,17,0]
   , p "pretty" [1,1,3,6]
-  , p "process" [1,6,19,0]
+  , p "process" [1,6,25,0] -- bumped via BUMP_LIBRARIES
+  , p "rts" [1,0,2]
   , p "semaphore-compat" [1,0,0]
   , p "stm" [2,5,3,1]
   , p "template-haskell" [2,22,0,0]
@@ -322,8 +445,9 @@
   , p "bytestring" [0,12,1,0]
   , p "containers" [0,6,8]
   , p "deepseq" [1,5,1,0]
-  , p "directory" [1,3,8,5]
+  , p "directory" [1,3,9,0] -- bumped via BUMP_LIBRARIES
   , p "exceptions" [0,10,7]
+  , p "file-io" [0,1,5] -- added via hadrian patch and BUMP_LIBRARIES
   , p "filepath" [1,4,301,0]
   , p "ghc-bignum" [1,3]
   , p "ghc-compact" [0,1,0,0]
@@ -335,6 +459,7 @@
   , p "parsec" [3,1,17,0]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,25,0]
+  , p "rts" [1,0,2]
   , p "semaphore-compat" [1,0,0]
   , p "stm" [2,5,3,1]
   , p "template-haskell" [2,21,0,0]
@@ -356,9 +481,10 @@
   , p "bytestring" [0,12,1,0]
   , p "containers" [0,6,8]
   , p "deepseq" [1,5,1,0]
-  , p "directory" [1,3,8,5]
+  , p "directory" [1,3,9,0] -- bumped via BUMP_LIBRARIES
   , p "exceptions" [0,10,7]
-  , p "filepath" [1,4,200,1] -- needs to be bumped to 1.4.300.1
+  , p "file-io" [0,1,5] -- added via hadrian patch and BUMP_LIBRARIES
+  , p "filepath" [1,4,301,0] -- bumped via BUMP_LIBRARIES
   , p "ghc-bignum" [1,3]
   , p "ghc-compact" [0,1,0,0]
   , p "ghc-prim" [0,11,0]
@@ -369,6 +495,7 @@
   , p "parsec" [3,1,17,0]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,25,0]
+  , p "rts" [1,0,2]
   , p "semaphore-compat" [1,0,0]
   , p "stm" [2,5,3,1]
   , p "template-haskell" [2,21,0,0]
@@ -376,7 +503,7 @@
   , p "text" [2,1,1]
   , p "time" [1,12,2]
   , p "transformers" [0,6,1,0]
-  , p "unix" [2,8,4,0]
+  , p "unix" [2,8,6,0] -- bumped via BUMP_LIBRARIES
   , p "xhtml" [3000,2,2,1]
   ]
 
@@ -384,15 +511,16 @@
 ghc982_pkgs =
   [ p "Cabal-syntax" [3,10,3,0] -- bumped via BUMP_LIBRARIES
   , p "Cabal" [3,10,3,0] -- bumped via BUMP_LIBRARIES
-  , p "array" [0,5,6,0]
+  , p "array" [0,5,8,0] -- bumped via BUMP_LIBRARIES
   , p "base" [4,19,1,0]
   , p "binary" [0,8,9,1]
   , p "bytestring" [0,12,1,0]
   , p "containers" [0,6,8]
   , p "deepseq" [1,5,0,0]
-  , p "directory" [1,3,8,5] -- bumped via BUMP_LIBRARIES
+  , p "directory" [1,3,9,0] -- bumped via BUMP_LIBRARIES
   , p "exceptions" [0,10,7]
-  , p "filepath" [1,4,300,1] -- bumped via BUMP_LIBRARIES
+  , p "file-io" [0,1,5] -- added via hadrian patch and BUMP_LIBRARIES
+  , p "filepath" [1,4,301,0] -- bumped via BUMP_LIBRARIES
   , p "ghc-bignum" [1,3]
   , p "ghc-compact" [0,1,0,0]
   , p "ghc-prim" [0,11,0]
@@ -402,18 +530,54 @@
   , p "mtl" [2,3,1]
   , p "parsec" [3,1,17,0]
   , p "pretty" [1,1,3,6]
-  , p "process" [1,6,19,0] -- bumped via BUMP_LIBRARIES
+  , p "process" [1,6,25,0] -- bumped via BUMP_LIBRARIES
+  , p "rts" [1,0,2]
   , p "semaphore-compat" [1,0,0]
-  , p "stm" [2,5,2,1]
+  , p "stm" [2,5,3,1] -- bumped via BUMP_LIBRARIES
   , p "template-haskell" [2,21,0,0]
   , p "terminfo" [0,4,1,6]
   , p "text" [2,1,1]
   , p "time" [1,12,2]
   , p "transformers" [0,6,1,0]
-  , p "unix" [2,8,4,0]
+  , p "unix" [2,8,6,0] -- bumped via BUMP_LIBRARIES
   , p "xhtml" [3000,2,2,1]
   ]
 
+ghc967_pkgs :: [Cabal.PackageIdentifier]
+ghc967_pkgs =
+  [ p "Cabal-syntax" [3,10,3,0]
+  , p "Cabal" [3,10,3,0]
+  , p "array" [0,5,8,0]
+  , p "base" [4,18,3,0]
+  , p "binary" [0,8,9,1]
+  , p "bytestring" [0,11,5,4]
+  , p "containers" [0,6,7]
+  , p "deepseq" [1,4,8,1]
+  , p "directory" [1,3,9,0] -- bumped via BUMP_LIBRARIES
+  , p "exceptions" [0,10,7]
+  , p "file-io" [0,1,5] -- added via hadrian patch and BUMP_LIBRARIES
+  , p "filepath" [1,4,301,0]
+  , p "ghc-bignum" [1,3]
+  , p "ghc-compact" [0,1,0,0]
+  , p "ghc-prim" [0,10,0]
+  , p "haskeline" [0,8,2,1]
+  , p "hpc" [0,6,2,0]
+  , p "integer-gmp" [1,1]
+  , p "mtl" [2,3,1]
+  , p "parsec" [3,1,16,1]
+  , p "pretty" [1,1,3,6]
+  , p "process" [1,6,19,0]
+  , p "rts" [1,0,2]
+  , p "stm" [2,5,1,0]
+  , p "template-haskell" [2,20,0,0]
+  , p "terminfo" [0,4,1,6]
+  , p "text" [2,0,2]
+  , p "time" [1,12,2]
+  , p "transformers" [0,6,1,0]
+  , p "unix" [2,8,6,0]
+  , p "xhtml" [3000,2,2,1]
+  ]
+
 ghc966_pkgs :: [Cabal.PackageIdentifier]
 ghc966_pkgs =
   [ p "Cabal-syntax" [3,10,3,0]
@@ -437,6 +601,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,19,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,20,0,0]
   , p "terminfo" [0,4,1,6]
@@ -471,6 +636,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,19,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,20,0,0]
   , p "terminfo" [0,4,1,6]
@@ -504,6 +670,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,18,0] -- bumped via BUMP_LIBRARIES
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,20,0,0]
   , p "terminfo" [0,4,1,6]
@@ -537,6 +704,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,18,0] -- bumped via BUMP_LIBRARIES
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,20,0,0]
   , p "terminfo" [0,4,1,6]
@@ -570,6 +738,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,17,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,20,0,0]
   , p "terminfo" [0,4,1,6]
@@ -603,6 +772,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,18,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,19,0,0]
   , p "terminfo" [0,4,1,5]
@@ -636,6 +806,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,17,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,19,0,0]
   , p "terminfo" [0,4,1,5]
@@ -669,6 +840,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,17,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,19,0,0]
   , p "terminfo" [0,4,1,5]
@@ -702,6 +874,7 @@
   , p "parsec" [3,1,16,1]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,16,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,1,0]
   , p "template-haskell" [2,19,0,0]
   , p "terminfo" [0,4,1,5]
@@ -734,6 +907,7 @@
   , p "parsec" [3,1,15,0]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,16,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,0,2]
   , p "template-haskell" [2,18,0,0]
   , p "terminfo" [0,4,1,5]
@@ -766,6 +940,7 @@
   , p "parsec" [3,1,15,0]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,16,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,0,2]
   , p "template-haskell" [2,18,0,0]
   , p "terminfo" [0,4,1,5]
@@ -798,6 +973,7 @@
   , p "parsec" [3,1,15,0]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,16,0]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,0,2]
   , p "template-haskell" [2,18,0,0]
   , p "terminfo" [0,4,1,5]
@@ -831,6 +1007,7 @@
   , p "parsec" [3,1,15,0]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,13,2]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,0,2]
   , p "template-haskell" [2,18,0,0]
   , p "terminfo" [0,4,1,5]
@@ -863,6 +1040,7 @@
   , p "parsec" [3,1,14,0]
   , p "pretty" [1,1,3,6]
   , p "process" [1,6,13,2]
+  , p "rts" [1,0,2]
   , p "stm" [2,5,0,0]
   , p "template-haskell" [2,17,0,0]
   , p "terminfo" [0,4,1,5]
diff --git a/tests/doctests-v2/Main.hs b/tests/doctests-v2/Main.hs
--- a/tests/doctests-v2/Main.hs
+++ b/tests/doctests-v2/Main.hs
@@ -1,14 +1,27 @@
+{-# LANGUAGE CPP #-}
+
 module Main (main) where
 
 import Data.Foldable (for_)
 import System.Exit (ExitCode (..), exitWith)
-import System.Process (readProcess, createProcess, proc, waitForProcess, getProcessExitCode)
+import System.Process (createProcess, proc, waitForProcess, getProcessExitCode)
 
+#ifdef EXTERNAL_DOCTEST
+import System.Directory (findExecutable)
+#else
+import System.Process (readProcess)
+#endif
 
+
 main :: IO ()
 main = do
 
+#ifdef EXTERNAL_DOCTEST
+    doctestPath <- findExecutable "doctest"
+        >>= maybe (error "Cannot find doctest exe") pure
+#else
     doctestPath:_ <- lines <$> readProcess "cabal" ["list-bin", "doctest"] []
+#endif
 
     let components =
             [ "hackport:lib:hackport-internal"
