{-# LANGUAGE CPP, RecordWildCards, NamedFieldPuns #-} #ifndef MIN_VERSION_Cabal #define MIN_VERSION_Cabal(x,y,z) 0 #endif #if MIN_VERSION_Cabal(2,0,0) -- https://github.com/haskell/cabal/pull/4501 is upstream in 2.0, yey import Distribution.Simple main = defaultMain #else import Distribution.Simple import Distribution.Simple.Utils import Distribution.Simple.Setup import Distribution.Simple.Install import Distribution.Simple.Register import Distribution.Simple.BuildPaths import qualified Distribution.Simple.InstallDirs as ID import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program import Distribution.PackageDescription import Control.Monad import Data.List import Data.Maybe import System.FilePath import System.Directory (renameFile) main :: IO () main = defaultMainWithHooks $ simpleUserHooks { instHook = inst, copyHook = copy, buildHook = \pd lbi hooks flags -> (buildHook simpleUserHooks) pd (patchLibexecdir lbi) hooks flags, hookedPrograms = [ simpleProgram "cabal" ] } patchLibexecdir :: LocalBuildInfo -> LocalBuildInfo patchLibexecdir lbi = let idirtpl = installDirTemplates lbi libexecdir' = toPathTemplate $ fromPathTemplate (libexecdir idirtpl) "$abi/$pkgid" lbi' = lbi { installDirTemplates = idirtpl { libexecdir = libexecdir' } } in lbi' -- mostly copypasta from 'defaultInstallHook' inst :: PackageDescription -> LocalBuildInfo -> UserHooks -> InstallFlags -> IO () inst pd lbi _uf ifl = do let copyFlags = defaultCopyFlags { copyDistPref = installDistPref ifl, copyDest = toFlag NoCopyDest, copyVerbosity = installVerbosity ifl } xInstallTarget pd lbi copyFlags (\pd' lbi' -> install pd' lbi' copyFlags) let registerFlags = defaultRegisterFlags { regDistPref = installDistPref ifl, regInPlace = installInPlace ifl, regPackageDB = installPackageDB ifl, regVerbosity = installVerbosity ifl } when (hasLibs pd) $ register pd lbi registerFlags copy :: PackageDescription -> LocalBuildInfo -> UserHooks -> CopyFlags -> IO () copy pd lbi _uh cf = xInstallTarget pd lbi cf (\pd' lbi' -> install pd' lbi' cf) xInstallTarget :: PackageDescription -> LocalBuildInfo -> CopyFlags -> (PackageDescription -> LocalBuildInfo -> IO ()) -> IO () xInstallTarget pd lbi cf fn = do let (extended, regular) = partition isExeScopePrivate (executables pd) let pd_regular = pd { executables = regular } _ <- flip mapM extended $ \exe -> do let pd_extended = onlyExePackageDesc [exe] pd fn pd_extended lbi let lbi' = patchLibexecdir lbi copydest = fromFlag (copyDest cf) verbosity = fromFlag (copyVerbosity cf) InstallDirs { bindir, libexecdir } = absoluteInstallDirs pd lbi' copydest progprefix = substPathTemplate (packageId pd) lbi (progPrefix lbi) progsuffix = substPathTemplate (packageId pd) lbi (progSuffix lbi) fixedExeBaseName = progprefix ++ exeName exe ++ progsuffix fixedExeFileName = bindir fixedExeBaseName <.> exeExtension newExeFileName = libexecdir fixedExeBaseName <.> exeExtension createDirectoryIfMissingVerbose verbosity True libexecdir renameFile fixedExeFileName newExeFileName fn pd_regular lbi isExeScopePrivate :: Executable -> Bool isExeScopePrivate exe = fromMaybe False $ (=="private") <$> lookup "x-scope" fields where fields = customFieldsBI $ buildInfo exe onlyExePackageDesc :: [Executable] -> PackageDescription -> PackageDescription onlyExePackageDesc exes pd = emptyPackageDescription { package = package pd , executables = exes } #endif