haskell.compiler.ghc{914,HEAD}: fix Cabal Paths_ patch for darwin

Rebased the patch set on the 3.16 branch of Cabal:
https://github.com/sternenseemann/cabal/tree/sterni-cabal-3.16-for-aarch64-darwin
This commit is contained in:
sternenseemann
2025-11-06 11:58:49 +01:00
parent b1703f49e5
commit 2163a16acc
2 changed files with 838 additions and 1 deletions

View File

@@ -0,0 +1,835 @@
This patch is based on https://github.com/sternenseemann/cabal/tree/sterni-cabal-3.16-for-aarch64-darwin and has been created using
git diff 77afa40961a686d36717604864b4c48ed5233bea eeed4f92625bbe2dbfb57f51d953e3b9a495d884 --patch --src-prefix=a/libraries/Cabal/ --dst-prefix=b/libraries/Cabal/
Reasoning and explanation of the patch can be found in the comment in the diff for PathsModule.hs below.
diff --git a/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule.hs b/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule.hs
index 9392acf3c..3417e613a 100644
--- a/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule.hs
+++ b/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule.hs
@@ -52,6 +52,7 @@ generatePathsModule pkg_descr lbi clbi =
, Z.zIsI386 = buildArch == I386
, Z.zIsX8664 = buildArch == X86_64
, Z.zIsAArch64 = buildArch == AArch64
+ , Z.zOr = (||)
, Z.zNot = not
, Z.zManglePkgName = showPkgName
, Z.zPrefix = show flat_prefix
@@ -61,8 +62,110 @@ generatePathsModule pkg_descr lbi clbi =
, Z.zDatadir = zDatadir
, Z.zLibexecdir = zLibexecdir
, Z.zSysconfdir = zSysconfdir
+ , -- Sadly we can't be cleverer about this we can't have literals in the template
+ Z.zShouldEmitDataDir = shouldEmit "DataDir"
+ , Z.zShouldEmitLibDir = shouldEmit "LibDir"
+ , Z.zShouldEmitDynLibDir = shouldEmit "DynLibDir"
+ , Z.zShouldEmitLibexecDir = shouldEmit "LibexecDir"
+ , Z.zShouldEmitSysconfDir = shouldEmit "SysconfDir"
+ , Z.zWarning = zWarning
+ , Z.zShouldEmitWarning = zShouldEmitWarning
}
where
+ -- GHC's NCG backend for aarch64-darwin does not support link-time dead code
+ -- elimination to the extent that NCG does for other targets. Consequently,
+ -- we struggle with unnecessarily retained store path references due to the
+ -- use of `Paths_*` modules even if `getLibDir` is not used, it'll end up
+ -- in the final library or executables we build.
+ --
+ -- When using a different output for the executables and library, this
+ -- becomes more sinister: The library will contain a reference to the bin
+ -- output and itself due to `getLibDir` and `getBinDir`, but the executables
+ -- will do so, too. Either due to linking dynamically or because the library
+ -- is linked statically into the executable and retains those references.
+ -- Since Nix disallows cyclical references between two outputs, it becomes
+ -- impossible to use the `Paths_*` module and a separate `bin` output for
+ -- aarch64-darwin.
+ --
+ -- The solution we have resorted to for now, is to trim the `Paths_*` module
+ -- dynamically depending on what references *could* be used without causing
+ -- a cyclical reference. That has the effect that any code that would not
+ -- cause a cyclical reference with dead code elimination will compile and
+ -- work for aarch64-darwin. If the code would use a `get*Dir` function that
+ -- has been omitted, this would indicate that the code would have caused a
+ -- cyclical reference anyways.
+ --
+ -- The logic for this makes some pretty big assumptions about installation
+ -- prefixes that probably only hold fully in nixpkgs with
+ -- `haskellPackages.mkDerivation`. Simple uses outside nixpkgs that have
+ -- everything below the same prefix should continue to work as expected,
+ -- though.
+ --
+ -- We assume the following:
+ --
+ -- - flat_prefix is `$out`.
+ -- - flat_libdir etc. are always below `$out`.
+ --
+ -- Since in the normal case due to static linking `$bin` and `$out` will
+ -- have the same references in libraries/executables, we need to either
+ -- prevent usage of `getBinDir` or `getLibDir` to break the cycle in case
+ -- `flat_bindir` is not below `$out`. We have decided to always allow usage
+ -- of `getBinDir`, so `getLibDir` gets dropped if a separate `bin` output is
+ -- used. This has the simple reason that `$out` which contains `flat_libdir`
+ -- tends to be quite big we would like to have a `bin` output that doesn't
+ -- require keeping that around.
+ pathEmittable :: FilePath -> Bool
+ pathEmittable p
+ -- If the executable installation target is below `$out` the reference
+ -- cycle is within a single output (since libs are installed to `$out`)
+ -- and thus unproblematic. We can use any and all `get*Dir` functions.
+ | flat_prefix `isPrefixOf` flat_bindir = True
+ -- Otherwise, we need to disallow all `get*Dir` functions that would cause
+ -- a reference to `$out` which contains the libraries that would in turn
+ -- reference `$bin`. This always include `flat_libdir` and friends, but
+ -- can also include `flat_datadir` if no separate output for data files is
+ -- used.
+ | otherwise = not (flat_prefix `isPrefixOf` p)
+
+ -- This list maps the "name" of the directory to whether we want to include
+ -- it in the `Paths_*` module or not. `shouldEmit` performs a lookup in this.
+ dirs :: [(String, Bool)]
+ dirs =
+ map
+ (\(name, path) -> (name, pathEmittable path))
+ [ ("LibDir", flat_libdir)
+ , ("DynLibDir", flat_dynlibdir)
+ , ("DataDir", flat_datadir)
+ , ("LibexecDir", flat_libexecdir)
+ , ("SysconfDir", flat_sysconfdir)
+ ]
+
+ shouldEmit :: String -> Bool
+ shouldEmit name =
+ case lookup name dirs of
+ Just b -> b
+ Nothing -> error "panic! BUG in Cabal Paths_ patch for aarch64-darwin, report this at https://github.com/nixos/nixpkgs/issues"
+
+ -- This is a comma separated list of all functions that have been omitted.
+ -- This is included in a GHC warning which will be attached to the `Paths_*`
+ -- module in case we are dropping any `get*Dir` functions that would
+ -- normally exist.
+ --
+ -- TODO: getDataFileName is not accounted for at the moment.
+ omittedFunctions :: String
+ omittedFunctions =
+ intercalate ", " $
+ map (("get" ++) . fst) $
+ filter (not . snd) dirs
+
+ zWarning :: String
+ zWarning =
+ show $
+ "The following functions have been omitted by a nixpkgs-specific patch to Cabal: "
+ ++ omittedFunctions
+ zShouldEmitWarning :: Bool
+ zShouldEmitWarning = any (not . snd) dirs
+
supports_cpp = supports_language_pragma
supports_rebindable_syntax = ghc_newer_than (mkVersion [7, 0, 1])
supports_language_pragma = ghc_newer_than (mkVersion [6, 6, 1])
diff --git a/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs b/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs
index 8f33717bb..b89775893 100644
--- a/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs
+++ b/libraries/Cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs
@@ -20,6 +20,14 @@ data Z
zDatadir :: FilePath,
zLibexecdir :: FilePath,
zSysconfdir :: FilePath,
+ zShouldEmitLibDir :: Bool,
+ zShouldEmitDynLibDir :: Bool,
+ zShouldEmitLibexecDir :: Bool,
+ zShouldEmitDataDir :: Bool,
+ zShouldEmitSysconfDir :: Bool,
+ zShouldEmitWarning :: Bool,
+ zWarning :: String,
+ zOr :: (Bool -> Bool -> Bool),
zNot :: (Bool -> Bool),
zManglePkgName :: (PackageName -> String)}
deriving Generic
@@ -74,10 +82,51 @@ render z_root = execWriter $ do
tell "\n"
tell "module Paths_"
tell (zManglePkgName z_root (zPackageName z_root))
- tell " (\n"
+ tell "\n"
+ tell " "
+ if (zShouldEmitWarning z_root)
+ then do
+ tell "{-# WARNING "
+ tell (zWarning z_root)
+ tell " #-}"
+ return ()
+ else do
+ return ()
+ tell "\n"
+ tell " (\n"
tell " version,\n"
- tell " getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,\n"
- tell " getDataFileName, getSysconfDir\n"
+ tell " getBinDir,\n"
+ if (zOr z_root (zNot z_root (zAbsolute z_root)) (zShouldEmitLibDir z_root))
+ then do
+ tell " getLibDir,\n"
+ return ()
+ else do
+ return ()
+ if (zOr z_root (zNot z_root (zAbsolute z_root)) (zShouldEmitDynLibDir z_root))
+ then do
+ tell " getDynLibDir,\n"
+ return ()
+ else do
+ return ()
+ if (zOr z_root (zNot z_root (zAbsolute z_root)) (zShouldEmitLibexecDir z_root))
+ then do
+ tell " getLibexecDir,\n"
+ return ()
+ else do
+ return ()
+ if (zOr z_root (zNot z_root (zAbsolute z_root)) (zShouldEmitDataDir z_root))
+ then do
+ tell " getDataFileName,\n"
+ tell " getDataDir,\n"
+ return ()
+ else do
+ return ()
+ if (zOr z_root (zNot z_root (zAbsolute z_root)) (zShouldEmitSysconfDir z_root))
+ then do
+ tell " getSysconfDir\n"
+ return ()
+ else do
+ return ()
tell " ) where\n"
tell "\n"
if (zNot z_root (zAbsolute z_root))
@@ -126,57 +175,19 @@ render z_root = execWriter $ do
tell (zVersionDigits z_root)
tell " []\n"
tell "\n"
- tell "-- |If the argument is a filename, the result is the name of a corresponding\n"
- tell "-- file on the system on which the program is running, if the file were listed\n"
- tell "-- in the @data-files@ field of the package's Cabal package description file.\n"
- tell "-- No check is performed that the given filename is listed in that field.\n"
- tell "getDataFileName :: FilePath -> IO FilePath\n"
- tell "getDataFileName name = do\n"
- tell " dir <- getDataDir\n"
- tell " return (dir `joinFileName` name)\n"
- tell "\n"
- tell "-- |The location of the directory specified by Cabal's @--bindir@ option (where\n"
- tell "-- executables that the user might invoke are installed). This can be overridden\n"
- tell "-- at runtime using the environment variable "
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_bindir.\n"
- tell "getBinDir :: IO FilePath\n"
- tell "\n"
- tell "-- |The location of the directory specified by Cabal's @--libdir@ option (where\n"
- tell "-- object libraries are installed). This can be overridden at runtime using the\n"
- tell "-- environment variable "
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_libdir.\n"
- tell "getLibDir :: IO FilePath\n"
- tell "\n"
- tell "-- |The location of the directory specified by Cabal's @--dynlibdir@ option\n"
- tell "-- (where dynamic libraries are installed). This can be overridden at runtime\n"
- tell "-- using the environment variable "
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_dynlibdir.\n"
- tell "getDynLibDir :: IO FilePath\n"
- tell "\n"
- tell "-- |The location of the directory specified by Cabal's @--datadir@ option (where\n"
- tell "-- architecture-independent data files are installed). This can be overridden at\n"
- tell "-- runtime using the environment variable "
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_datadir.\n"
- tell "getDataDir :: IO FilePath\n"
- tell "\n"
- tell "-- |The location of the directory specified by Cabal's @--libexedir@ option\n"
- tell "-- (where executables that are not expected to be invoked directly by the user\n"
- tell "-- are installed). This can be overridden at runtime using the environment\n"
- tell "-- variable "
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_libexedir.\n"
- tell "getLibexecDir :: IO FilePath\n"
- tell "\n"
- tell "-- |The location of the directory specified by Cabal's @--sysconfdir@ option\n"
- tell "-- (where configuration files are installed). This can be overridden at runtime\n"
- tell "-- using the environment variable "
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_sysconfdir.\n"
- tell "getSysconfDir :: IO FilePath\n"
+ if (zOr z_root (zNot z_root (zAbsolute z_root)) (zShouldEmitDataDir z_root))
+ then do
+ tell "-- |If the argument is a filename, the result is the name of a corresponding\n"
+ tell "-- file on the system on which the program is running, if the file were listed\n"
+ tell "-- in the @data-files@ field of the package's Cabal package description file.\n"
+ tell "-- No check is performed that the given filename is listed in that field.\n"
+ tell "getDataFileName :: FilePath -> IO FilePath\n"
+ tell "getDataFileName name = do\n"
+ tell " dir <- getDataDir\n"
+ tell " return (dir `joinFileName` name)\n"
+ return ()
+ else do
+ return ()
tell "\n"
let
z_var0_function_defs = do
@@ -204,6 +215,7 @@ render z_root = execWriter $ do
tell "\n"
if (zRelocatable z_root)
then do
+ tell "\n"
tell "\n"
tell "getPrefixDirReloc :: FilePath -> IO FilePath\n"
tell "getPrefixDirReloc dirRel = do\n"
@@ -213,31 +225,68 @@ render z_root = execWriter $ do
tell (zBindir z_root)
tell ") `joinFileName` dirRel)\n"
tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--bindir@ option (where\n"
+ tell "-- executables that the user might invoke are installed). This can be overridden\n"
+ tell "-- at runtime using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_bindir.\n"
+ tell "getBinDir :: IO FilePath\n"
tell "getBinDir = catchIO (getEnv \""
tell (zManglePkgName z_root (zPackageName z_root))
tell "_bindir\") (\\_ -> getPrefixDirReloc $ "
tell (zBindir z_root)
tell ")\n"
+ tell "-- |The location of the directory specified by Cabal's @--libdir@ option (where\n"
+ tell "-- object libraries are installed). This can be overridden at runtime using the\n"
+ tell "-- environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libdir.\n"
+ tell "getLibDir :: IO FilePath\n"
tell "getLibDir = catchIO (getEnv \""
tell (zManglePkgName z_root (zPackageName z_root))
tell "_libdir\") (\\_ -> getPrefixDirReloc $ "
tell (zLibdir z_root)
tell ")\n"
+ tell "-- |The location of the directory specified by Cabal's @--dynlibdir@ option\n"
+ tell "-- (where dynamic libraries are installed). This can be overridden at runtime\n"
+ tell "-- using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_dynlibdir.\n"
+ tell "getDynLibDir :: IO FilePath\n"
tell "getDynLibDir = catchIO (getEnv \""
tell (zManglePkgName z_root (zPackageName z_root))
tell "_dynlibdir\") (\\_ -> getPrefixDirReloc $ "
tell (zDynlibdir z_root)
tell ")\n"
+ tell "-- |The location of the directory specified by Cabal's @--datadir@ option (where\n"
+ tell "-- architecture-independent data files are installed). This can be overridden at\n"
+ tell "-- runtime using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_datadir.\n"
+ tell "getDataDir :: IO FilePath\n"
tell "getDataDir = catchIO (getEnv \""
tell (zManglePkgName z_root (zPackageName z_root))
tell "_datadir\") (\\_ -> getPrefixDirReloc $ "
tell (zDatadir z_root)
tell ")\n"
+ tell "-- |The location of the directory specified by Cabal's @--libexedir@ option\n"
+ tell "-- (where executables that are not expected to be invoked directly by the user\n"
+ tell "-- are installed). This can be overridden at runtime using the environment\n"
+ tell "-- variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libexedir.\n"
+ tell "getLibexecDir :: IO FilePath\n"
tell "getLibexecDir = catchIO (getEnv \""
tell (zManglePkgName z_root (zPackageName z_root))
tell "_libexecdir\") (\\_ -> getPrefixDirReloc $ "
tell (zLibexecdir z_root)
tell ")\n"
+ tell "-- |The location of the directory specified by Cabal's @--sysconfdir@ option\n"
+ tell "-- (where configuration files are installed). This can be overridden at runtime\n"
+ tell "-- using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_sysconfdir.\n"
+ tell "getSysconfDir :: IO FilePath\n"
tell "getSysconfDir = catchIO (getEnv \""
tell (zManglePkgName z_root (zPackageName z_root))
tell "_sysconfdir\") (\\_ -> getPrefixDirReloc $ "
@@ -251,72 +300,186 @@ render z_root = execWriter $ do
if (zAbsolute z_root)
then do
tell "\n"
- tell "bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath\n"
+ tell "bindir :: FilePath\n"
tell "bindir = "
tell (zBindir z_root)
tell "\n"
- tell "libdir = "
- tell (zLibdir z_root)
tell "\n"
- tell "dynlibdir = "
- tell (zDynlibdir z_root)
+ tell "-- |The location of the directory specified by Cabal's @--bindir@ option (where\n"
+ tell "-- executables that the user might invoke are installed). This can be overridden\n"
+ tell "-- at runtime using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_bindir.\n"
+ tell "getBinDir :: IO FilePath\n"
+ tell "getBinDir = catchIO (getEnv \""
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_bindir\") (\\_ -> return bindir)\n"
tell "\n"
- tell "datadir = "
- tell (zDatadir z_root)
+ if (zShouldEmitLibDir z_root)
+ then do
+ tell "libdir :: FilePath\n"
+ tell "libdir = "
+ tell (zLibdir z_root)
+ tell "\n"
+ tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--libdir@ option (where\n"
+ tell "-- object libraries are installed). This can be overridden at runtime using the\n"
+ tell "-- environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libdir.\n"
+ tell "getLibDir :: IO FilePath\n"
+ tell "getLibDir = catchIO (getEnv \""
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libdir\") (\\_ -> return libdir)\n"
+ return ()
+ else do
+ return ()
tell "\n"
- tell "libexecdir = "
- tell (zLibexecdir z_root)
+ if (zShouldEmitDynLibDir z_root)
+ then do
+ tell "dynlibdir :: FilePath\n"
+ tell "dynlibdir = "
+ tell (zDynlibdir z_root)
+ tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--dynlibdir@ option\n"
+ tell "-- (where dynamic libraries are installed). This can be overridden at runtime\n"
+ tell "-- using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_dynlibdir.\n"
+ tell "getDynLibDir :: IO FilePath\n"
+ tell "getDynLibDir = catchIO (getEnv \""
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_dynlibdir\") (\\_ -> return dynlibdir)\n"
+ return ()
+ else do
+ return ()
tell "\n"
- tell "sysconfdir = "
- tell (zSysconfdir z_root)
+ if (zShouldEmitDataDir z_root)
+ then do
+ tell "datadir :: FilePath\n"
+ tell "datadir = "
+ tell (zDatadir z_root)
+ tell "\n"
+ tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--datadir@ option (where\n"
+ tell "-- architecture-independent data files are installed). This can be overridden at\n"
+ tell "-- runtime using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_datadir.\n"
+ tell "getDataDir :: IO FilePath\n"
+ tell "getDataDir = catchIO (getEnv \""
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_datadir\") (\\_ -> return datadir)\n"
+ return ()
+ else do
+ return ()
tell "\n"
+ if (zShouldEmitLibexecDir z_root)
+ then do
+ tell "libexecdir :: FilePath\n"
+ tell "libexecdir = "
+ tell (zLibexecdir z_root)
+ tell "\n"
+ tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--libexedir@ option\n"
+ tell "-- (where executables that are not expected to be invoked directly by the user\n"
+ tell "-- are installed). This can be overridden at runtime using the environment\n"
+ tell "-- variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libexedir.\n"
+ tell "getLibexecDir :: IO FilePath\n"
+ tell "getLibexecDir = catchIO (getEnv \""
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libexecdir\") (\\_ -> return libexecdir)\n"
+ return ()
+ else do
+ return ()
tell "\n"
- tell "getBinDir = catchIO (getEnv \""
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_bindir\") (\\_ -> return bindir)\n"
- tell "getLibDir = catchIO (getEnv \""
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_libdir\") (\\_ -> return libdir)\n"
- tell "getDynLibDir = catchIO (getEnv \""
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_dynlibdir\") (\\_ -> return dynlibdir)\n"
- tell "getDataDir = catchIO (getEnv \""
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_datadir\") (\\_ -> return datadir)\n"
- tell "getLibexecDir = catchIO (getEnv \""
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_libexecdir\") (\\_ -> return libexecdir)\n"
- tell "getSysconfDir = catchIO (getEnv \""
- tell (zManglePkgName z_root (zPackageName z_root))
- tell "_sysconfdir\") (\\_ -> return sysconfdir)\n"
+ if (zShouldEmitSysconfDir z_root)
+ then do
+ tell "sysconfdir :: FilePath\n"
+ tell "sysconfdir = "
+ tell (zSysconfdir z_root)
+ tell "\n"
+ tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--sysconfdir@ option\n"
+ tell "-- (where configuration files are installed). This can be overridden at runtime\n"
+ tell "-- using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_sysconfdir.\n"
+ tell "getSysconfDir :: IO FilePath\n"
+ tell "getSysconfDir = catchIO (getEnv \""
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_sysconfdir\") (\\_ -> return sysconfdir)\n"
+ return ()
+ else do
+ return ()
tell "\n"
return ()
else do
if (zIsWindows z_root)
then do
+ tell "\n"
tell "\n"
tell "prefix :: FilePath\n"
tell "prefix = "
tell (zPrefix z_root)
tell "\n"
tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--bindir@ option (where\n"
+ tell "-- executables that the user might invoke are installed). This can be overridden\n"
+ tell "-- at runtime using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_bindir.\n"
+ tell "getBinDir :: IO FilePath\n"
tell "getBinDir = getPrefixDirRel $ "
tell (zBindir z_root)
tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--libdir@ option (where\n"
+ tell "-- object libraries are installed). This can be overridden at runtime using the\n"
+ tell "-- environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libdir.\n"
+ tell "getLibDir :: IO FilePath\n"
tell "getLibDir = "
tell (zLibdir z_root)
tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--dynlibdir@ option\n"
+ tell "-- (where dynamic libraries are installed). This can be overridden at runtime\n"
+ tell "-- using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_dynlibdir.\n"
+ tell "getDynLibDir :: IO FilePath\n"
tell "getDynLibDir = "
tell (zDynlibdir z_root)
tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--datadir@ option (where\n"
+ tell "-- architecture-independent data files are installed). This can be overridden at\n"
+ tell "-- runtime using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_datadir.\n"
+ tell "getDataDir :: IO FilePath\n"
tell "getDataDir = catchIO (getEnv \""
tell (zManglePkgName z_root (zPackageName z_root))
tell "_datadir\") (\\_ -> "
tell (zDatadir z_root)
tell ")\n"
+ tell "-- |The location of the directory specified by Cabal's @--libexedir@ option\n"
+ tell "-- (where executables that are not expected to be invoked directly by the user\n"
+ tell "-- are installed). This can be overridden at runtime using the environment\n"
+ tell "-- variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_libexedir.\n"
+ tell "getLibexecDir :: IO FilePath\n"
tell "getLibexecDir = "
tell (zLibexecdir z_root)
tell "\n"
+ tell "-- |The location of the directory specified by Cabal's @--sysconfdir@ option\n"
+ tell "-- (where configuration files are installed). This can be overridden at runtime\n"
+ tell "-- using the environment variable "
+ tell (zManglePkgName z_root (zPackageName z_root))
+ tell "_sysconfdir.\n"
+ tell "getSysconfDir :: IO FilePath\n"
tell "getSysconfDir = "
tell (zSysconfdir z_root)
tell "\n"
diff --git a/libraries/Cabal/cabal-dev-scripts/src/GenPathsModule.hs b/libraries/Cabal/cabal-dev-scripts/src/GenPathsModule.hs
index 7c5c947a5..3b7a67498 100644
--- a/libraries/Cabal/cabal-dev-scripts/src/GenPathsModule.hs
+++ b/libraries/Cabal/cabal-dev-scripts/src/GenPathsModule.hs
@@ -42,6 +42,16 @@ $(capture "decls" [d|
, zLibexecdir :: FilePath
, zSysconfdir :: FilePath
+ , zShouldEmitLibDir :: Bool
+ , zShouldEmitDynLibDir :: Bool
+ , zShouldEmitLibexecDir :: Bool
+ , zShouldEmitDataDir :: Bool
+ , zShouldEmitSysconfDir :: Bool
+
+ , zShouldEmitWarning :: Bool
+ , zWarning :: String
+
+ , zOr :: Bool -> Bool -> Bool
, zNot :: Bool -> Bool
, zManglePkgName :: PackageName -> String
}
diff --git a/libraries/Cabal/templates/Paths_pkg.template.hs b/libraries/Cabal/templates/Paths_pkg.template.hs
index a9b02b0ef..d99252a29 100644
--- a/libraries/Cabal/templates/Paths_pkg.template.hs
+++ b/libraries/Cabal/templates/Paths_pkg.template.hs
@@ -31,10 +31,31 @@ For further information about Cabal's options for its configuration step, and
their default values, see the Cabal User Guide.
-}
-module Paths_{{ manglePkgName packageName }} (
+module Paths_{{ manglePkgName packageName }}
+ {% if shouldEmitWarning %}{-# WARNING {{ warning }} #-}{% endif %}
+ (
version,
- getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
- getDataFileName, getSysconfDir
+ getBinDir,
+{# We only care about the absolute case for our emit logic, since only in this
+ case references are incurred. We are not going to hit isWindows and relocatable
+ has no absolute references to begin with.
+#}
+{% if or (not absolute) shouldEmitLibDir %}
+ getLibDir,
+{% endif %}
+{% if or (not absolute) shouldEmitDynLibDir %}
+ getDynLibDir,
+{% endif %}
+{% if or (not absolute) shouldEmitLibexecDir %}
+ getLibexecDir,
+{% endif %}
+{% if or (not absolute) shouldEmitDataDir %}
+ getDataFileName,
+ getDataDir,
+{% endif %}
+{% if or (not absolute) shouldEmitSysconfDir %}
+ getSysconfDir
+{% endif %}
) where
{% if not absolute %}
@@ -73,6 +94,7 @@ catchIO = Exception.catch
version :: Version
version = Version {{ versionDigits }} []
+{% if or (not absolute) shouldEmitDataDir %}
-- |If the argument is a filename, the result is the name of a corresponding
-- file on the system on which the program is running, if the file were listed
-- in the @data-files@ field of the package's Cabal package description file.
@@ -81,37 +103,7 @@ getDataFileName :: FilePath -> IO FilePath
getDataFileName name = do
dir <- getDataDir
return (dir `joinFileName` name)
-
--- |The location of the directory specified by Cabal's @--bindir@ option (where
--- executables that the user might invoke are installed). This can be overridden
--- at runtime using the environment variable {{ manglePkgName packageName }}_bindir.
-getBinDir :: IO FilePath
-
--- |The location of the directory specified by Cabal's @--libdir@ option (where
--- object libraries are installed). This can be overridden at runtime using the
--- environment variable {{ manglePkgName packageName }}_libdir.
-getLibDir :: IO FilePath
-
--- |The location of the directory specified by Cabal's @--dynlibdir@ option
--- (where dynamic libraries are installed). This can be overridden at runtime
--- using the environment variable {{ manglePkgName packageName }}_dynlibdir.
-getDynLibDir :: IO FilePath
-
--- |The location of the directory specified by Cabal's @--datadir@ option (where
--- architecture-independent data files are installed). This can be overridden at
--- runtime using the environment variable {{ manglePkgName packageName }}_datadir.
-getDataDir :: IO FilePath
-
--- |The location of the directory specified by Cabal's @--libexedir@ option
--- (where executables that are not expected to be invoked directly by the user
--- are installed). This can be overridden at runtime using the environment
--- variable {{ manglePkgName packageName }}_libexedir.
-getLibexecDir :: IO FilePath
-
--- |The location of the directory specified by Cabal's @--sysconfdir@ option
--- (where configuration files are installed). This can be overridden at runtime
--- using the environment variable {{ manglePkgName packageName }}_sysconfdir.
-getSysconfDir :: IO FilePath
+{% endif %}
{% defblock function_defs %}
minusFileName :: FilePath -> String -> FilePath
@@ -140,48 +132,155 @@ splitFileName p = (reverse (path2++drive), reverse fname)
{% if relocatable %}
+{# Relocatable can not incur any absolute references, so we can ignore it.
+ Additionally, --enable-relocatable is virtually useless in Nix builds
+#}
+
getPrefixDirReloc :: FilePath -> IO FilePath
getPrefixDirReloc dirRel = do
exePath <- getExecutablePath
let (dir,_) = splitFileName exePath
return ((dir `minusFileName` {{ bindir }}) `joinFileName` dirRel)
+-- |The location of the directory specified by Cabal's @--bindir@ option (where
+-- executables that the user might invoke are installed). This can be overridden
+-- at runtime using the environment variable {{ manglePkgName packageName }}_bindir.
+getBinDir :: IO FilePath
getBinDir = catchIO (getEnv "{{ manglePkgName packageName }}_bindir") (\_ -> getPrefixDirReloc $ {{ bindir }})
+-- |The location of the directory specified by Cabal's @--libdir@ option (where
+-- object libraries are installed). This can be overridden at runtime using the
+-- environment variable {{ manglePkgName packageName }}_libdir.
+getLibDir :: IO FilePath
getLibDir = catchIO (getEnv "{{ manglePkgName packageName }}_libdir") (\_ -> getPrefixDirReloc $ {{ libdir }})
+-- |The location of the directory specified by Cabal's @--dynlibdir@ option
+-- (where dynamic libraries are installed). This can be overridden at runtime
+-- using the environment variable {{ manglePkgName packageName }}_dynlibdir.
+getDynLibDir :: IO FilePath
getDynLibDir = catchIO (getEnv "{{ manglePkgName packageName }}_dynlibdir") (\_ -> getPrefixDirReloc $ {{ dynlibdir }})
+-- |The location of the directory specified by Cabal's @--datadir@ option (where
+-- architecture-independent data files are installed). This can be overridden at
+-- runtime using the environment variable {{ manglePkgName packageName }}_datadir.
+getDataDir :: IO FilePath
getDataDir = catchIO (getEnv "{{ manglePkgName packageName }}_datadir") (\_ -> getPrefixDirReloc $ {{ datadir }})
+-- |The location of the directory specified by Cabal's @--libexedir@ option
+-- (where executables that are not expected to be invoked directly by the user
+-- are installed). This can be overridden at runtime using the environment
+-- variable {{ manglePkgName packageName }}_libexedir.
+getLibexecDir :: IO FilePath
getLibexecDir = catchIO (getEnv "{{ manglePkgName packageName }}_libexecdir") (\_ -> getPrefixDirReloc $ {{ libexecdir }})
+-- |The location of the directory specified by Cabal's @--sysconfdir@ option
+-- (where configuration files are installed). This can be overridden at runtime
+-- using the environment variable {{ manglePkgName packageName }}_sysconfdir.
+getSysconfDir :: IO FilePath
getSysconfDir = catchIO (getEnv "{{ manglePkgName packageName }}_sysconfdir") (\_ -> getPrefixDirReloc $ {{ sysconfdir }})
{% useblock function_defs %}
{% elif absolute %}
-bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir :: FilePath
bindir = {{ bindir }}
-libdir = {{ libdir }}
-dynlibdir = {{ dynlibdir }}
-datadir = {{ datadir }}
-libexecdir = {{ libexecdir }}
-sysconfdir = {{ sysconfdir }}
+-- |The location of the directory specified by Cabal's @--bindir@ option (where
+-- executables that the user might invoke are installed). This can be overridden
+-- at runtime using the environment variable {{ manglePkgName packageName }}_bindir.
+getBinDir :: IO FilePath
getBinDir = catchIO (getEnv "{{ manglePkgName packageName }}_bindir") (\_ -> return bindir)
+
+{% if shouldEmitLibDir %}
+libdir :: FilePath
+libdir = {{ libdir }}
+
+-- |The location of the directory specified by Cabal's @--libdir@ option (where
+-- object libraries are installed). This can be overridden at runtime using the
+-- environment variable {{ manglePkgName packageName }}_libdir.
+getLibDir :: IO FilePath
getLibDir = catchIO (getEnv "{{ manglePkgName packageName }}_libdir") (\_ -> return libdir)
+{% endif %}
+
+{% if shouldEmitDynLibDir %}
+dynlibdir :: FilePath
+dynlibdir = {{ dynlibdir }}
+-- |The location of the directory specified by Cabal's @--dynlibdir@ option
+-- (where dynamic libraries are installed). This can be overridden at runtime
+-- using the environment variable {{ manglePkgName packageName }}_dynlibdir.
+getDynLibDir :: IO FilePath
getDynLibDir = catchIO (getEnv "{{ manglePkgName packageName }}_dynlibdir") (\_ -> return dynlibdir)
+{% endif %}
+
+{% if shouldEmitDataDir %}
+datadir :: FilePath
+datadir = {{ datadir }}
+
+-- |The location of the directory specified by Cabal's @--datadir@ option (where
+-- architecture-independent data files are installed). This can be overridden at
+-- runtime using the environment variable {{ manglePkgName packageName }}_datadir.
+getDataDir :: IO FilePath
getDataDir = catchIO (getEnv "{{ manglePkgName packageName }}_datadir") (\_ -> return datadir)
+{% endif %}
+
+{% if shouldEmitLibexecDir %}
+libexecdir :: FilePath
+libexecdir = {{ libexecdir }}
+
+-- |The location of the directory specified by Cabal's @--libexedir@ option
+-- (where executables that are not expected to be invoked directly by the user
+-- are installed). This can be overridden at runtime using the environment
+-- variable {{ manglePkgName packageName }}_libexedir.
+getLibexecDir :: IO FilePath
getLibexecDir = catchIO (getEnv "{{ manglePkgName packageName }}_libexecdir") (\_ -> return libexecdir)
+{% endif %}
+
+{% if shouldEmitSysconfDir %}
+sysconfdir :: FilePath
+sysconfdir = {{ sysconfdir }}
+
+-- |The location of the directory specified by Cabal's @--sysconfdir@ option
+-- (where configuration files are installed). This can be overridden at runtime
+-- using the environment variable {{ manglePkgName packageName }}_sysconfdir.
+getSysconfDir :: IO FilePath
getSysconfDir = catchIO (getEnv "{{ manglePkgName packageName }}_sysconfdir") (\_ -> return sysconfdir)
+{% endif %}
{% elif isWindows %}
+{# We are only trying to fix the problem for aarch64-darwin with this patch,
+ so let's ignore Windows which we can reach via pkgsCross, for example.
+#}
+
prefix :: FilePath
prefix = {{ prefix }}
+-- |The location of the directory specified by Cabal's @--bindir@ option (where
+-- executables that the user might invoke are installed). This can be overridden
+-- at runtime using the environment variable {{ manglePkgName packageName }}_bindir.
+getBinDir :: IO FilePath
getBinDir = getPrefixDirRel $ {{ bindir }}
+-- |The location of the directory specified by Cabal's @--libdir@ option (where
+-- object libraries are installed). This can be overridden at runtime using the
+-- environment variable {{ manglePkgName packageName }}_libdir.
+getLibDir :: IO FilePath
getLibDir = {{ libdir }}
+-- |The location of the directory specified by Cabal's @--dynlibdir@ option
+-- (where dynamic libraries are installed). This can be overridden at runtime
+-- using the environment variable {{ manglePkgName packageName }}_dynlibdir.
+getDynLibDir :: IO FilePath
getDynLibDir = {{ dynlibdir }}
+-- |The location of the directory specified by Cabal's @--datadir@ option (where
+-- architecture-independent data files are installed). This can be overridden at
+-- runtime using the environment variable {{ manglePkgName packageName }}_datadir.
+getDataDir :: IO FilePath
getDataDir = catchIO (getEnv "{{ manglePkgName packageName }}_datadir") (\_ -> {{ datadir }})
+-- |The location of the directory specified by Cabal's @--libexedir@ option
+-- (where executables that are not expected to be invoked directly by the user
+-- are installed). This can be overridden at runtime using the environment
+-- variable {{ manglePkgName packageName }}_libexedir.
+getLibexecDir :: IO FilePath
getLibexecDir = {{ libexecdir }}
+-- |The location of the directory specified by Cabal's @--sysconfdir@ option
+-- (where configuration files are installed). This can be overridden at runtime
+-- using the environment variable {{ manglePkgName packageName }}_sysconfdir.
+getSysconfDir :: IO FilePath
getSysconfDir = {{ sysconfdir }}
getPrefixDirRel :: FilePath -> IO FilePath

View File

@@ -205,8 +205,10 @@
(
if lib.versionOlder version "9.10" then
./Cabal-at-least-3.6-paths-fix-cycle-aarch64-darwin.patch
else
else if lib.versionOlder version "9.14" then
./Cabal-3.12-paths-fix-cycle-aarch64-darwin.patch
else
./Cabal-3.16-paths-fix-cycle-aarch64-darwin.patch
)
]
++ lib.optionals stdenv.targetPlatform.isWindows [