diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -2,6 +2,14 @@
 
 `simple-cabal` uses [PVP Versioning](https://pvp.haskell.org)
 
+## 0.2.1 (2026-02-08, @juhp)
+- mark allBuildInfo deprecated
+- add readFinalPackageDescription' (fixes #4)
+- use listToMaybe to drop safe (fixes #5)
+- add findCabalFile' (closes #3)
+- add back tryFindPackageDesc
+- Cabal 3.16 compatibility (#6, @sol)
+
 ## 0.2.0 (2025-09-17)
 - support Cabal 3.14:
 - readGenericPackageDescription' replaces readGenericPackageDescription
diff --git a/SimpleCabal.hs b/SimpleCabal.hs
deleted file mode 100644
--- a/SimpleCabal.hs
+++ /dev/null
@@ -1,453 +0,0 @@
-{-# LANGUAGE CPP #-}
-
-module SimpleCabal (
-  findCabalFile,
-  readFinalPackageDescription,
-  finalPackageDescription,
-#if MIN_VERSION_Cabal(2,2,0)
-  parseFinalPackageDescription,
-#endif
-  makeFinalPackageDescription,
-  getPackageId,
---  dependencies,
-#if MIN_VERSION_Cabal(2,4,0)
-  buildDepends,
-#endif
-  buildDependencies,
-  setupDependencies,
-  testsuiteDependencies,
-
-  allBuildInfo, -- deprecated by allLibraries et al
-  allLibraries,
-  BuildInfo (..),
-  Library(..),
-  depPkgName, exeDepName, pkgcfgDepName,
-#if MIN_VERSION_Cabal(2,0,0)
-  UnqualComponentName, mkUnqualComponentName,
-#endif
-  unUnqualComponentName,
-  FlagName, mkFlagName,
-  hasExes, hasLibs,
-#if !MIN_VERSION_Cabal(1,20,0)
-  licenseFiles,
-#endif
-  PackageDescription (..),
-  PackageIdentifier (..),
-  PackageName, mkPackageName, unPackageName,
-  packageName, packageVersion,
-  readGenericPackageDescription',
-  showPkgId,
-  showVersion,
-  simpleParse,
-#if MIN_VERSION_Cabal(2,2,0)
-  simpleParsec,
-#endif
-  tryFindPackageDesc'
-  ) where
-
-#if MIN_VERSION_base(4,8,0)
-#else
-import Control.Applicative ((<$>))
-#endif
-
-#if MIN_VERSION_Cabal(2,2,0)
-import qualified Data.ByteString.Char8 as B
-#endif
-#if !MIN_VERSION_Cabal(2,0,0)
-import Data.Maybe (maybeToList)
-#endif
-import Data.List (delete, nub)
-
-import Distribution.Compiler
-import Distribution.Package  (
-                              packageName,
-#if MIN_VERSION_Cabal(1,22,0)
-#if MIN_VERSION_Cabal(2,0,0)
-                              depPkgName,
-                              mkPackageName,
-                              unPackageName,
-                              unPkgconfigName,
-#if MIN_VERSION_Cabal(2,4,0)
-                              Dependency,
-#endif
-#else
-#endif
-#endif
-#if MIN_VERSION_Cabal(2,0,0)
-#else
-                              Dependency (..),
-#endif
-#if MIN_VERSION_Cabal(2,0,0)
-                              PackageName,
-#else
-                              PackageName (..),
-#endif
-                              PackageIdentifier (..),
-                                       )
-
-import Distribution.PackageDescription (
-  PackageDescription (..),
-  allBuildInfo,
-#if MIN_VERSION_Cabal(2,0,0)
-  allLibraries,
-#endif
-  BuildInfo (..),
---  buildToolDepends,
-#if MIN_VERSION_Cabal(2,4,0)
-  enabledBuildDepends,
-#endif
-  extraLibs,
-#if MIN_VERSION_Cabal(2,0,0)
-  FlagName,
-  mkFlagName,
-#else
-  FlagName (..),
-#endif
-  GenericPackageDescription(packageDescription),
-  hasExes, hasLibs,
-  Library(..),
-#if MIN_VERSION_Cabal(2,2,0)
-  mkFlagAssignment,
-#endif
-  pkgconfigDepends,
-#if MIN_VERSION_Cabal(1,24,0)
-  setupDepends,
-#endif
-  targetBuildDepends,
-  TestSuite (..)
-  )
-#if MIN_VERSION_Cabal(2,0,0)
-import Distribution.PackageDescription.Configuration (finalizePD)
-import Distribution.Types.ComponentRequestedSpec (defaultComponentRequestedSpec)
-import Distribution.Types.LegacyExeDependency (LegacyExeDependency (..))
-import Distribution.Types.PkgconfigDependency (PkgconfigDependency (..))
-import Distribution.Types.UnqualComponentName (UnqualComponentName(),
-                                               mkUnqualComponentName,
-                                               unUnqualComponentName
-                                              )
-#else
-import Distribution.PackageDescription.Configuration (finalizePackageDescription)
-#endif
-#if MIN_VERSION_Cabal(2,2,0)
-import qualified Distribution.PackageDescription.Parsec as DPP
-#elif MIN_VERSION_Cabal(2,0,0)
-import qualified Distribution.PackageDescription.Parse as DPP
-#else
-import qualified Distribution.PackageDescription.Parse as DPP
-#endif
-
-#if MIN_VERSION_Cabal(3,0,0)
-import Distribution.Parsec (simpleParsec)
-#else
-#if MIN_VERSION_Cabal(2,2,0)
-import Distribution.Parsec.Class (simpleParsec)
-#endif
-#endif
-
-import Distribution.Simple.Compiler (
-#if MIN_VERSION_Cabal(1,22,0)
-    compilerInfo
-#else
-    Compiler (..)
-#endif
-    )
-import Distribution.Simple.Configure (
-#if MIN_VERSION_Cabal(1,18,0)
-    configCompilerEx
-#else
-    configCompiler
-#endif
-    )
-#if MIN_VERSION_Cabal(3,8,0)
-import qualified Distribution.Simple.PackageDescription as DSP
-#endif
-#if MIN_VERSION_Cabal(2,0,0)
---import Distribution.Simple.BuildToolDepends (getAllToolDependencies)
-import Distribution.Simple.Program   (defaultProgramDb)
-#else
-import Distribution.Simple.Program   (defaultProgramConfiguration)
-#endif
-#if MIN_VERSION_Cabal(3,14,0)
-import Distribution.Utils.Path (interpretSymbolicPath, makeSymbolicPath)
-#endif
-import qualified Distribution.Simple.Utils as DSU (
-#if MIN_VERSION_Cabal(1,20,0)
-    tryFindPackageDesc
-#else
-    findPackageDesc
-#endif
-    )
-import Distribution.System (Platform (..), buildArch, buildOS)
-
-import Distribution.Text (simpleParse)
-
-import Distribution.Verbosity (normal, Verbosity
-                              )
-
-#if MIN_VERSION_Cabal(2,2,0)
-import Distribution.Pretty (prettyShow)
-#else
-#if MIN_VERSION_Cabal(2,0,0)
-import Distribution.Version (showVersion)
-#else
-import Data.Version (showVersion)
-#endif
-#endif
-
-#if MIN_VERSION_Cabal(2,2,0)
-import qualified Distribution.Version (Version)
-#endif
-
-import Safe (headMay)
-import System.Directory (getDirectoryContents)
-import System.FilePath (takeExtension)
-
--- | Find the .cabal file in the current directory.
---
--- Errors if more than one or no file found.
---
--- @since 0.0.0.1
-findCabalFile :: IO FilePath
-findCabalFile = do
-  allCabals <- filesWithExtension "." ".cabal"
-  case allCabals of
-    [file] -> return file
-    [] -> error "No .cabal file found"
-    _ -> error "More than one .cabal file found!"
-  where
-    filesWithExtension :: FilePath -> String -> IO [FilePath]
-    filesWithExtension dir ext =
-      filter (\ f -> takeExtension f == ext && headMay f /= Just '.')
-      <$> getDirectoryContents dir
-
--- | Get the package name-version from the .cabal file in the current directory.
---
--- @since 0.0.0.1
-getPackageId :: IO PackageIdentifier
-getPackageId = do
-  gpd <- findCabalFile >>= readGenericPackageDescription' normal
-  return $ package $ packageDescription gpd
-
-#if MIN_VERSION_Cabal(2,2,0)
--- | only available with Cabal-2.2+
---
--- @since 0.1.2
-parseFinalPackageDescription :: [(FlagName, Bool)] -> B.ByteString
-                          -> IO (Maybe PackageDescription)
-parseFinalPackageDescription flags cabalfile = do
-  let mgenPkgDesc = DPP.parseGenericPackageDescriptionMaybe cabalfile
-  case mgenPkgDesc of
-    Nothing -> return Nothing
-    Just genPkgDesc -> Just <$> makeFinalPackageDescription flags genPkgDesc
-#endif
-
--- | Generate PackageDescription from the specified .cabal file and flags.
---
--- deprecated in favour of readFinalPackageDescription
---
--- @since 0.0.0.1
-finalPackageDescription :: [(FlagName, Bool)] -> FilePath
-                          -> IO PackageDescription
-finalPackageDescription = readFinalPackageDescription
-
--- | Legacy version of readGenericPackageDescription
--- which doesn't use SymbolicPath (or workdir)
---
--- since 0.2.0
-readGenericPackageDescription' :: Verbosity -> FilePath -> IO GenericPackageDescription
-readGenericPackageDescription' verb file =
-#if MIN_VERSION_Cabal(3,8,0)
-  DSP.readGenericPackageDescription verb
-#elif MIN_VERSION_Cabal(2,0,0)
-  DPP.readGenericPackageDescription verb
-#else
-  DPP.readPackageDescription verb
-#endif
---  DPP.readGenericPackageDescription verb
-#if MIN_VERSION_Cabal(3,14,0)
-    Nothing $
-    makeSymbolicPath
-#endif
-    file
-
-
--- | get PackageDescription from a cabal file
---
--- deprecates finalPackageDescription
---
--- @since 0.1.2
-readFinalPackageDescription :: [(FlagName, Bool)] -> FilePath
-                            -> IO PackageDescription
-readFinalPackageDescription flags cabalfile =
-  readGenericPackageDescription' normal cabalfile >>=
-  makeFinalPackageDescription flags
-
--- | convert a GenericPackageDescription to a final PackageDescription
---
--- @since 0.1.2
-makeFinalPackageDescription :: [(FlagName, Bool)] -> GenericPackageDescription
-                            -> IO PackageDescription
-makeFinalPackageDescription flags genPkgDesc = do
-#if !MIN_VERSION_Cabal(2,0,0)
-  let defaultProgramDb = defaultProgramConfiguration
-#endif
-  compiler <- do
-#if MIN_VERSION_Cabal(1,18,0)
-    (compiler, _, _) <- configCompilerEx
-#else
-    (compiler, _) <- configCompiler
-#endif
-       (Just GHC) Nothing Nothing defaultProgramDb normal
-#if MIN_VERSION_Cabal(1,22,0)
-    return (compilerInfo compiler)
-#else
-    return (compilerId compiler)
-#endif
-#if !MIN_VERSION_Cabal(2,2,0)
-  let mkFlagAssignment = id
-#endif
-#if MIN_VERSION_Cabal(2,0,0)
-  let finalizePackageDescription flags' = finalizePD flags' defaultComponentRequestedSpec
-#endif
-  let final =
-        finalizePackageDescription (mkFlagAssignment flags)
-        (const True) (Platform buildArch buildOS)
-        compiler
-        [] genPkgDesc
-  case final of
-    Left e -> error $ "finalize failed: " ++ show e
-    Right res -> return $ fst res
-
--- | Return the list of build dependencies of a package, excluding itself
-buildDependencies :: PackageDescription -> [PackageName]
-buildDependencies pkgDesc =
-  let deps = nub $ map depPkgName (buildDepends pkgDesc)
-      self = pkgName $ package pkgDesc
-  in delete self deps
-
--- | Return the list of testsuite dependencies of a package, excluding itself
-testsuiteDependencies :: PackageDescription -> [PackageName]
-testsuiteDependencies pkgDesc =
-  let self = pkgName $ package pkgDesc in
-  delete self . nub . map depPkgName $ concatMap (targetBuildDepends . testBuildInfo) (testSuites pkgDesc)
-
--- | version string from PackageIdentifier
-packageVersion :: PackageIdentifier -> String
-packageVersion =
-#if MIN_VERSION_Cabal(2,2,0)
-  prettyShow . pkgVersion
-#else
-  showVersion . pkgVersion
-#endif
-
--- | convert PackageIdentifier to a displayable string
-showPkgId :: PackageIdentifier -> String
-showPkgId pkgid =
-#if MIN_VERSION_Cabal(2,2,0)
-  prettyShow pkgid
-#else
-  unPackageName (packageName pkgid) ++ "-" ++ packageVersion pkgid
-#endif
-
-#if !MIN_VERSION_Cabal(1,22,0)
-unPackageName :: PackageName -> String
-unPackageName (PackageName n) = n
-#endif
-
-#if MIN_VERSION_Cabal(2,2,0)
--- | render a Version
-showVersion :: Distribution.Version.Version -> String
-showVersion = prettyShow
-#endif
-
-#if !MIN_VERSION_Cabal(2,0,0)
-mkFlagName :: String -> FlagName
-mkFlagName = FlagName
-#endif
-
--- | Find cabal file in current directory
---
--- since 0.2.0
-tryFindPackageDesc' :: IO FilePath
-tryFindPackageDesc' =
-#if MIN_VERSION_Cabal(3,14,0)
-  interpretSymbolicPath Nothing <$> DSU.tryFindPackageDesc normal Nothing
-#elif MIN_VERSION_Cabal(3,0,0)
-  DSU.tryFindPackageDesc normal "."
-#elif MIN_VERSION_Cabal(1,20,0)
-  DSU.tryFindPackageDesc "."
-#else
-  DSU.findPackageDesc "."
-#endif
-
-#if !MIN_VERSION_Cabal(1,20,0)
--- | singleton list of license file
-licenseFiles :: PackageDescription -> [FilePath]
-licenseFiles pkgDesc =
-  [licenseFile pkgDesc | licenseFile pkgDesc /= ""]
-#endif
-
-#if MIN_VERSION_Cabal(2,4,0)
--- | List build dependencies
-buildDepends :: PackageDescription -> [Dependency]
-buildDepends = flip enabledBuildDepends defaultComponentRequestedSpec
-#endif
-
-#if MIN_VERSION_Cabal(2,0,0)
--- | name of legacy exe dep
-exeDepName :: LegacyExeDependency -> String
-exeDepName (LegacyExeDependency n _) = n
-
--- | pkgconfig dep name
-pkgcfgDepName :: PkgconfigDependency -> String
-pkgcfgDepName (PkgconfigDependency n _) = unPkgconfigName n
-#else
--- | PackageName of dependency
-depPkgName :: Dependency -> PackageName
-depPkgName (Dependency pn _) = pn
-
--- | name of dependency
-exeDepName :: Dependency -> String
-exeDepName = unPackageName . depPkgName
-
--- | name of dependency
-pkgcfgDepName :: Dependency -> String
-pkgcfgDepName = unPackageName . depPkgName
-
--- | name of unqualified component
-unUnqualComponentName :: String -> String
-unUnqualComponentName = id
-#endif
-
-#if !MIN_VERSION_Cabal(2,0,0)
-mkPackageName :: String -> PackageName
-mkPackageName = PackageName
-#endif
-
--- | List of setup dependencies
-setupDependencies :: PackageDescription  -- ^pkg description
-                  -> [PackageName]         -- ^depends
-#if MIN_VERSION_Cabal(1,24,0)
-setupDependencies pkgDesc =
-  maybe [] (map depPkgName . setupDepends) (setupBuildInfo pkgDesc)
-#else
-setupDependencies _pkgDesc = []
-#endif
-
--- dependencies :: PackageDescription  -- ^pkg description
---                 -> ([PackageName], [PackageName], [ExeDependency], [String], [PkgconfigDependency])
---                 -- ^depends, setup, tools, c-libs, pkgcfg
--- dependencies pkgDesc =
---     let --self = pkgName $ package pkgDesc
---         deps = buildDependencies pkgDesc
---         setup = setupDependencies pkgDesc
---         buildinfo = allBuildInfo pkgDesc
---         tools =  nub $ concatMap buildToolDepends buildinfo
---         clibs = nub $ concatMap extraLibs buildinfo
---         pkgcfgs = nub $ concatMap pkgconfigDepends buildinfo
---     in (deps, setup, tools, clibs, pkgcfgs)
-
-#if !MIN_VERSION_Cabal(2,0,0)
-allLibraries :: PackageDescription -> [Library]
-allLibraries = maybeToList . library
-#endif
diff --git a/simple-cabal.cabal b/simple-cabal.cabal
--- a/simple-cabal.cabal
+++ b/simple-cabal.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >= 1.10
 name:                simple-cabal
-version:             0.2.0
+version:             0.2.1
 synopsis:            Cabal compatibility wrapper library
 description:         Find and read .cabal files, and
                      a Cabal dependency compatibility layer.
@@ -10,13 +10,13 @@
 license-file:        LICENSE
 author:              Jens Petersen
 maintainer:          juhpetersen@gmail.com
-copyright:           2019-2020,2022-2023,2025 Jens Petersen
+copyright:           2019-2020,2022-2023,2025-2026 Jens Petersen
 category:            Distribution
 build-type:          Simple
 extra-source-files:  README.md
                    , ChangeLog.md
-tested-with:         GHC == 9.12.2, GHC == 9.10.2, GHC == 9.8.4,
-                     GHC == 9.0.2, GHC == 9.2.8, GHC == 9.4.8, GHC == 9.6.7,
+tested-with:         GHC == 9.14.1, GHC == 9.12.3, GHC == 9.10.2, GHC == 9.8.4,
+                     GHC == 9.6.7, GHC == 9.4.8, GHC == 9.2.8, GHC == 9.0.2,
                      GHC == 8.10.7, GHC == 8.8.4, GHC == 8.6.5, GHC == 8.4.4,
                      GHC == 8.2.2, GHC == 8.0.2
 
@@ -26,13 +26,13 @@
 
 library
   exposed-modules:     SimpleCabal
+  hs-source-dirs:      src
 
   build-depends:       base < 5,
                        bytestring,
                        Cabal,
                        directory,
-                       filepath,
-                       safe
+                       filepath
 
   default-language:    Haskell2010
 
diff --git a/src/SimpleCabal.hs b/src/SimpleCabal.hs
new file mode 100644
--- /dev/null
+++ b/src/SimpleCabal.hs
@@ -0,0 +1,495 @@
+{-# LANGUAGE CPP #-}
+
+module SimpleCabal (
+  findCabalFile,
+  findCabalFile',
+  readFinalPackageDescription,
+  readFinalPackageDescription',
+  finalPackageDescription,
+#if MIN_VERSION_Cabal(2,2,0)
+  parseFinalPackageDescription,
+#endif
+  makeFinalPackageDescription,
+  getPackageId,
+--  dependencies,
+#if MIN_VERSION_Cabal(2,4,0)
+  buildDepends,
+#endif
+  buildDependencies,
+  setupDependencies,
+  testsuiteDependencies,
+
+  allBuildInfo, -- ^ deprecated by allLibraries et al
+  allLibraries,
+  BuildInfo (..),
+  Library(..),
+  depPkgName, exeDepName, pkgcfgDepName,
+#if MIN_VERSION_Cabal(2,0,0)
+  UnqualComponentName, mkUnqualComponentName,
+#endif
+  unUnqualComponentName,
+  FlagName, mkFlagName,
+  hasExes, hasLibs,
+#if !MIN_VERSION_Cabal(1,20,0)
+  licenseFiles,
+#endif
+  PackageDescription (..),
+  PackageIdentifier (..),
+  PackageName, mkPackageName, unPackageName,
+  packageName, packageVersion,
+  readGenericPackageDescription',
+  showPkgId,
+  showVersion,
+  simpleParse,
+#if MIN_VERSION_Cabal(2,2,0)
+  simpleParsec,
+#endif
+  tryFindPackageDesc,
+  tryFindPackageDesc'
+  ) where
+
+#if MIN_VERSION_base(4,8,0)
+#else
+import Control.Applicative ((<$>))
+#endif
+
+#if MIN_VERSION_Cabal(2,2,0)
+import qualified Data.ByteString.Char8 as B
+#endif
+import Data.Maybe (
+  listToMaybe,
+#if !MIN_VERSION_Cabal(2,0,0)
+  maybeToList
+#endif
+    )
+import Data.List (delete, nub)
+
+#if MIN_VERSION_Cabal(3,16,0)
+import Distribution.Types.DependencySatisfaction
+#endif
+
+import Distribution.Compiler
+import Distribution.Package  (
+                              packageName,
+#if MIN_VERSION_Cabal(1,22,0)
+#if MIN_VERSION_Cabal(2,0,0)
+                              depPkgName,
+                              mkPackageName,
+                              unPackageName,
+                              unPkgconfigName,
+#if MIN_VERSION_Cabal(2,4,0)
+                              Dependency,
+#endif
+#else
+#endif
+#endif
+#if MIN_VERSION_Cabal(2,0,0)
+#else
+                              Dependency (..),
+#endif
+#if MIN_VERSION_Cabal(2,0,0)
+                              PackageName,
+#else
+                              PackageName (..),
+#endif
+                              PackageIdentifier (..),
+                                       )
+
+import Distribution.PackageDescription (
+  PackageDescription (..),
+  allBuildInfo,
+#if MIN_VERSION_Cabal(2,0,0)
+  allLibraries,
+#endif
+  BuildInfo (..),
+--  buildToolDepends,
+#if MIN_VERSION_Cabal(2,4,0)
+  enabledBuildDepends,
+#endif
+  extraLibs,
+#if MIN_VERSION_Cabal(2,0,0)
+  FlagName,
+  mkFlagName,
+#else
+  FlagName (..),
+#endif
+  GenericPackageDescription(packageDescription),
+  hasExes, hasLibs,
+  Library(..),
+#if MIN_VERSION_Cabal(2,2,0)
+  mkFlagAssignment,
+#endif
+  pkgconfigDepends,
+#if MIN_VERSION_Cabal(1,24,0)
+  setupDepends,
+#endif
+  targetBuildDepends,
+  TestSuite (..)
+  )
+#if MIN_VERSION_Cabal(2,0,0)
+import Distribution.PackageDescription.Configuration (finalizePD)
+import Distribution.Types.ComponentRequestedSpec (defaultComponentRequestedSpec)
+import Distribution.Types.LegacyExeDependency (LegacyExeDependency (..))
+import Distribution.Types.PkgconfigDependency (PkgconfigDependency (..))
+import Distribution.Types.UnqualComponentName (UnqualComponentName(),
+                                               mkUnqualComponentName,
+                                               unUnqualComponentName
+                                              )
+#else
+import Distribution.PackageDescription.Configuration (finalizePackageDescription)
+#endif
+#if MIN_VERSION_Cabal(2,2,0)
+import qualified Distribution.PackageDescription.Parsec as DPP
+#elif MIN_VERSION_Cabal(2,0,0)
+import qualified Distribution.PackageDescription.Parse as DPP
+#else
+import qualified Distribution.PackageDescription.Parse as DPP
+#endif
+
+#if MIN_VERSION_Cabal(3,0,0)
+import Distribution.Parsec (simpleParsec)
+#else
+#if MIN_VERSION_Cabal(2,2,0)
+import Distribution.Parsec.Class (simpleParsec)
+#endif
+#endif
+
+import Distribution.Simple.Compiler (
+#if MIN_VERSION_Cabal(1,22,0)
+    compilerInfo
+#else
+    Compiler (..)
+#endif
+    )
+import Distribution.Simple.Configure (
+#if MIN_VERSION_Cabal(1,18,0)
+    configCompilerEx
+#else
+    configCompiler
+#endif
+    )
+#if MIN_VERSION_Cabal(3,8,0)
+import qualified Distribution.Simple.PackageDescription as DSP
+#endif
+#if MIN_VERSION_Cabal(2,0,0)
+--import Distribution.Simple.BuildToolDepends (getAllToolDependencies)
+import Distribution.Simple.Program   (defaultProgramDb)
+#else
+import Distribution.Simple.Program   (defaultProgramConfiguration)
+#endif
+#if MIN_VERSION_Cabal(3,14,0)
+import Distribution.Utils.Path (interpretSymbolicPath, makeSymbolicPath)
+#endif
+import qualified Distribution.Simple.Utils as DSU (
+#if MIN_VERSION_Cabal(1,20,0)
+    tryFindPackageDesc
+#else
+    findPackageDesc
+#endif
+    )
+import Distribution.System (Platform (..), buildArch, buildOS)
+
+import Distribution.Text (simpleParse)
+
+import Distribution.Verbosity (normal, Verbosity
+                              )
+
+#if MIN_VERSION_Cabal(2,2,0)
+import Distribution.Pretty (prettyShow)
+#else
+#if MIN_VERSION_Cabal(2,0,0)
+import Distribution.Version (showVersion)
+#else
+import Data.Version (showVersion)
+#endif
+#endif
+
+#if MIN_VERSION_Cabal(2,2,0)
+import qualified Distribution.Version (Version)
+#endif
+
+import System.Directory (getDirectoryContents,
+#if MIN_VERSION_directory(1,3,9)
+                         withCurrentDirectory
+#endif
+                        )
+import System.FilePath (normalise, takeExtension, (</>))
+
+-- | Find the .cabal file in the current directory.
+--
+-- Errors if more than one or no file found.
+--
+-- @since 0.0.0.1
+findCabalFile :: IO FilePath
+findCabalFile = findCabalFile' "."
+
+-- | Find .cabal file in a directory
+--
+-- Errors if more than one or no file found.
+--
+-- @since 0.2.1
+findCabalFile' :: FilePath -> IO FilePath
+findCabalFile' dir = do
+  allCabals <- filesWithExtension ".cabal"
+  case allCabals of
+    [file] -> return $ normalise $ dir </> file
+    [] -> error "No .cabal file found"
+    _ -> error "More than one .cabal file found!"
+  where
+    filesWithExtension :: String -> IO [FilePath]
+    filesWithExtension ext =
+      filter (\ f -> takeExtension f == ext && listToMaybe f /= Just '.')
+      <$> getDirectoryContents dir
+
+-- | Get the package name-version from the .cabal file in the current directory.
+--
+-- @since 0.0.0.1
+getPackageId :: IO PackageIdentifier
+getPackageId = do
+  gpd <- findCabalFile >>= readGenericPackageDescription' normal
+  return $ package $ packageDescription gpd
+
+#if MIN_VERSION_Cabal(2,2,0)
+-- | only available with Cabal-2.2+
+--
+-- @since 0.1.2
+parseFinalPackageDescription :: [(FlagName, Bool)] -> B.ByteString
+                          -> IO (Maybe PackageDescription)
+parseFinalPackageDescription flags cabalfile = do
+  let mgenPkgDesc = DPP.parseGenericPackageDescriptionMaybe cabalfile
+  case mgenPkgDesc of
+    Nothing -> return Nothing
+    Just genPkgDesc -> Just <$> makeFinalPackageDescription flags genPkgDesc
+#endif
+
+-- | Generate PackageDescription from the specified .cabal file and flags.
+--
+-- deprecated in favour of readFinalPackageDescription
+--
+-- @since 0.0.0.1
+finalPackageDescription :: [(FlagName, Bool)] -> FilePath
+                          -> IO PackageDescription
+finalPackageDescription = readFinalPackageDescription
+
+-- | Legacy version of readGenericPackageDescription
+-- which doesn't use SymbolicPath (or workdir)
+--
+-- since 0.2.0
+readGenericPackageDescription' :: Verbosity -> FilePath -> IO GenericPackageDescription
+readGenericPackageDescription' verb file =
+#if MIN_VERSION_Cabal(3,8,0)
+  DSP.readGenericPackageDescription verb
+#elif MIN_VERSION_Cabal(2,0,0)
+  DPP.readGenericPackageDescription verb
+#else
+  DPP.readPackageDescription verb
+#endif
+--  DPP.readGenericPackageDescription verb
+#if MIN_VERSION_Cabal(3,14,0)
+    Nothing $
+    makeSymbolicPath
+#endif
+    file
+
+
+-- | get PackageDescription from a cabal file
+--
+-- deprecates finalPackageDescription
+--
+-- @since 0.1.2
+readFinalPackageDescription :: [(FlagName, Bool)] -> FilePath
+                            -> IO PackageDescription
+readFinalPackageDescription flags cabalfile =
+  readGenericPackageDescription' normal cabalfile >>=
+  makeFinalPackageDescription flags
+
+-- | like readFinalPackageDescription but with a verbose parameter
+--
+-- @since 0.2.1
+readFinalPackageDescription' :: [(FlagName, Bool)] -> Verbosity -> FilePath
+                            -> IO PackageDescription
+readFinalPackageDescription' flags verbose cabalfile =
+  readGenericPackageDescription' verbose cabalfile >>=
+  makeFinalPackageDescription flags
+
+-- | convert a GenericPackageDescription to a final PackageDescription
+--
+-- @since 0.1.2
+makeFinalPackageDescription :: [(FlagName, Bool)] -> GenericPackageDescription
+                            -> IO PackageDescription
+makeFinalPackageDescription flags genPkgDesc = do
+#if !MIN_VERSION_Cabal(2,0,0)
+  let defaultProgramDb = defaultProgramConfiguration
+#endif
+  compiler <- do
+#if MIN_VERSION_Cabal(1,18,0)
+    (compiler, _, _) <- configCompilerEx
+#else
+    (compiler, _) <- configCompiler
+#endif
+       (Just GHC) Nothing Nothing defaultProgramDb normal
+#if MIN_VERSION_Cabal(1,22,0)
+    return (compilerInfo compiler)
+#else
+    return (compilerId compiler)
+#endif
+#if !MIN_VERSION_Cabal(2,2,0)
+  let mkFlagAssignment = id
+#endif
+#if MIN_VERSION_Cabal(2,0,0)
+  let finalizePackageDescription flags' = finalizePD flags' defaultComponentRequestedSpec
+#endif
+  let final =
+        finalizePackageDescription (mkFlagAssignment flags)
+#if MIN_VERSION_Cabal(3,16,0)
+        (const Satisfied)
+#else
+        (const True)
+#endif
+        (Platform buildArch buildOS)
+        compiler
+        [] genPkgDesc
+  case final of
+    Left e -> error $ "finalize failed: " ++ show e
+    Right res -> return $ fst res
+
+-- | Return the list of build dependencies of a package, excluding itself
+buildDependencies :: PackageDescription -> [PackageName]
+buildDependencies pkgDesc =
+  let deps = nub $ map depPkgName (buildDepends pkgDesc)
+      self = pkgName $ package pkgDesc
+  in delete self deps
+
+-- | Return the list of testsuite dependencies of a package, excluding itself
+testsuiteDependencies :: PackageDescription -> [PackageName]
+testsuiteDependencies pkgDesc =
+  let self = pkgName $ package pkgDesc in
+  delete self . nub . map depPkgName $ concatMap (targetBuildDepends . testBuildInfo) (testSuites pkgDesc)
+
+-- | version string from PackageIdentifier
+packageVersion :: PackageIdentifier -> String
+packageVersion =
+#if MIN_VERSION_Cabal(2,2,0)
+  prettyShow . pkgVersion
+#else
+  showVersion . pkgVersion
+#endif
+
+-- | convert PackageIdentifier to a displayable string
+showPkgId :: PackageIdentifier -> String
+showPkgId pkgid =
+#if MIN_VERSION_Cabal(2,2,0)
+  prettyShow pkgid
+#else
+  unPackageName (packageName pkgid) ++ "-" ++ packageVersion pkgid
+#endif
+
+#if !MIN_VERSION_Cabal(1,22,0)
+unPackageName :: PackageName -> String
+unPackageName (PackageName n) = n
+#endif
+
+#if MIN_VERSION_Cabal(2,2,0)
+-- | render a Version
+showVersion :: Distribution.Version.Version -> String
+showVersion = prettyShow
+#endif
+
+#if !MIN_VERSION_Cabal(2,0,0)
+mkFlagName :: String -> FlagName
+mkFlagName = FlagName
+#endif
+
+-- | Find cabal file in directory
+--
+-- reintroduced in 0.2.1
+tryFindPackageDesc :: FilePath -> IO FilePath
+tryFindPackageDesc dir =
+#if MIN_VERSION_Cabal(3,14,0)
+  do
+    file <- withCurrentDirectory dir $
+      interpretSymbolicPath Nothing <$> DSU.tryFindPackageDesc normal Nothing
+    return $ dir </> file
+#elif MIN_VERSION_Cabal(3,0,0)
+  DSU.tryFindPackageDesc normal dir
+#elif MIN_VERSION_Cabal(1,20,0)
+  DSU.tryFindPackageDesc dir
+#else
+  DSU.findPackageDesc dir
+#endif
+
+-- | Find cabal file in current directory
+tryFindPackageDesc' :: IO FilePath
+tryFindPackageDesc' = tryFindPackageDesc "."
+
+#if !MIN_VERSION_Cabal(1,20,0)
+-- | singleton list of license file
+licenseFiles :: PackageDescription -> [FilePath]
+licenseFiles pkgDesc =
+  [licenseFile pkgDesc | licenseFile pkgDesc /= ""]
+#endif
+
+#if MIN_VERSION_Cabal(2,4,0)
+-- | List build dependencies
+buildDepends :: PackageDescription -> [Dependency]
+buildDepends = flip enabledBuildDepends defaultComponentRequestedSpec
+#endif
+
+#if MIN_VERSION_Cabal(2,0,0)
+-- | name of legacy exe dep
+exeDepName :: LegacyExeDependency -> String
+exeDepName (LegacyExeDependency n _) = n
+
+-- | pkgconfig dep name
+pkgcfgDepName :: PkgconfigDependency -> String
+pkgcfgDepName (PkgconfigDependency n _) = unPkgconfigName n
+#else
+-- | PackageName of dependency
+depPkgName :: Dependency -> PackageName
+depPkgName (Dependency pn _) = pn
+
+-- | name of dependency
+exeDepName :: Dependency -> String
+exeDepName = unPackageName . depPkgName
+
+-- | name of dependency
+pkgcfgDepName :: Dependency -> String
+pkgcfgDepName = unPackageName . depPkgName
+
+-- | name of unqualified component
+unUnqualComponentName :: String -> String
+unUnqualComponentName = id
+#endif
+
+#if !MIN_VERSION_Cabal(2,0,0)
+mkPackageName :: String -> PackageName
+mkPackageName = PackageName
+#endif
+
+-- | List of setup dependencies
+setupDependencies :: PackageDescription  -- ^pkg description
+                  -> [PackageName]         -- ^depends
+#if MIN_VERSION_Cabal(1,24,0)
+setupDependencies pkgDesc =
+  maybe [] (map depPkgName . setupDepends) (setupBuildInfo pkgDesc)
+#else
+setupDependencies _pkgDesc = []
+#endif
+
+-- dependencies :: PackageDescription  -- ^pkg description
+--                 -> ([PackageName], [PackageName], [ExeDependency], [String], [PkgconfigDependency])
+--                 -- ^depends, setup, tools, c-libs, pkgcfg
+-- dependencies pkgDesc =
+--     let --self = pkgName $ package pkgDesc
+--         deps = buildDependencies pkgDesc
+--         setup = setupDependencies pkgDesc
+--         buildinfo = allBuildInfo pkgDesc
+--         tools =  nub $ concatMap buildToolDepends buildinfo
+--         clibs = nub $ concatMap extraLibs buildinfo
+--         pkgcfgs = nub $ concatMap pkgconfigDepends buildinfo
+--     in (deps, setup, tools, clibs, pkgcfgs)
+
+#if !MIN_VERSION_Cabal(2,0,0)
+allLibraries :: PackageDescription -> [Library]
+allLibraries = maybeToList . library
+#endif
