2015-02-04 00:12:51 +00:00
|
|
|
#!/usr/bin/env runhaskell
|
2017-05-17 21:59:29 +00:00
|
|
|
{-# LANGUAGE RecordWildCards, NamedFieldPuns #-}
|
2010-04-02 15:16:22 +00:00
|
|
|
import Distribution.Simple
|
2017-05-17 21:59:29 +00:00
|
|
|
import Distribution.Simple.Utils
|
2015-02-04 00:12:51 +00:00
|
|
|
import Distribution.Simple.Setup
|
|
|
|
import Distribution.Simple.Install
|
2017-03-01 07:26:17 +00:00
|
|
|
import Distribution.Simple.Program
|
2015-04-15 11:13:00 +00:00
|
|
|
import Distribution.Simple.Register
|
2017-05-17 21:59:29 +00:00
|
|
|
import Distribution.Simple.BuildPaths
|
|
|
|
import qualified Distribution.Simple.InstallDirs as ID
|
2015-01-16 14:46:58 +00:00
|
|
|
import Distribution.Simple.LocalBuildInfo
|
2015-02-04 00:12:51 +00:00
|
|
|
import Distribution.PackageDescription
|
2015-01-16 14:46:58 +00:00
|
|
|
|
2017-05-17 21:59:29 +00:00
|
|
|
import qualified Data.Map as M
|
|
|
|
import Data.Map (Map)
|
|
|
|
|
2015-02-04 00:12:51 +00:00
|
|
|
import Control.Arrow
|
2015-01-16 14:46:58 +00:00
|
|
|
import Control.Applicative
|
2015-02-04 00:12:51 +00:00
|
|
|
import Control.Monad
|
|
|
|
import Data.List
|
|
|
|
import Data.Maybe
|
2015-01-16 14:46:58 +00:00
|
|
|
import Data.Version
|
2015-02-04 00:12:51 +00:00
|
|
|
import Data.Monoid
|
2015-01-16 14:46:58 +00:00
|
|
|
import System.Process
|
|
|
|
import System.Exit
|
2015-02-04 00:12:51 +00:00
|
|
|
import System.FilePath
|
2017-05-17 21:59:29 +00:00
|
|
|
import System.Directory (renameFile)
|
2015-01-16 14:46:58 +00:00
|
|
|
|
|
|
|
main :: IO ()
|
|
|
|
main = defaultMainWithHooks $ simpleUserHooks {
|
2017-05-17 21:59:29 +00:00
|
|
|
instHook = inst,
|
|
|
|
copyHook = copy,
|
|
|
|
|
2015-02-04 00:12:51 +00:00
|
|
|
confHook = \(gpd, hbi) cf ->
|
2015-02-08 13:17:53 +00:00
|
|
|
xBuildDependsLike <$> (confHook simpleUserHooks) (gpd, hbi) cf
|
2017-05-17 21:59:29 +00:00
|
|
|
|
|
|
|
, buildHook = \pd lbi hooks flags -> (buildHook simpleUserHooks) pd (patchLibexecdir lbi) hooks flags
|
2017-03-01 07:26:17 +00:00
|
|
|
, hookedPrograms = [ simpleProgram "shelltest" ]
|
2015-02-04 00:12:51 +00:00
|
|
|
}
|
|
|
|
|
2017-05-17 21:59:29 +00:00
|
|
|
patchLibexecdir :: LocalBuildInfo -> LocalBuildInfo
|
|
|
|
patchLibexecdir lbi = let
|
|
|
|
idirtpl = installDirTemplates lbi
|
|
|
|
libexecdir' = toPathTemplate $ fromPathTemplate (libexecdir idirtpl) </> "$abi/$pkgid"
|
|
|
|
lbi' = lbi { installDirTemplates = idirtpl { libexecdir = libexecdir' } }
|
|
|
|
in
|
|
|
|
lbi'
|
|
|
|
|
|
|
|
|
2015-02-04 00:12:51 +00:00
|
|
|
xBuildDependsLike :: LocalBuildInfo -> LocalBuildInfo
|
|
|
|
xBuildDependsLike lbi =
|
|
|
|
let
|
|
|
|
cc = componentsConfigs lbi
|
|
|
|
pd = localPkgDescr lbi
|
|
|
|
deps = dependsMap lbi
|
2017-05-17 21:59:29 +00:00
|
|
|
in lbi {
|
|
|
|
componentsConfigs =
|
|
|
|
[ (cn, updateClbi deps comp clbi, cdeps)
|
|
|
|
| (cn, clbi, cdeps) <- cc
|
|
|
|
, let comp = getComponent pd cn
|
|
|
|
]
|
|
|
|
}
|
2015-02-04 00:12:51 +00:00
|
|
|
where
|
2015-02-08 13:17:53 +00:00
|
|
|
updateClbi deps comp clbi = setUnionDeps (otherDeps deps comp) clbi
|
2015-02-04 00:12:51 +00:00
|
|
|
|
2017-05-17 21:59:29 +00:00
|
|
|
-- dependsMap ::
|
|
|
|
-- LocalBuildInfo -> [(ComponentName, ([(UnitId, PackageId)], Map PackageName ModuleRenaming))]
|
2015-02-04 00:12:51 +00:00
|
|
|
dependsMap lbi =
|
2017-05-17 21:59:29 +00:00
|
|
|
second (componentPackageDeps &&& componentPackageRenaming)
|
|
|
|
<$> allComponentsInBuildOrder lbi
|
2015-02-04 00:12:51 +00:00
|
|
|
|
2017-05-17 21:59:29 +00:00
|
|
|
-- otherDeps :: [(ComponentName, ([(UnitId, PackageId)], Map PackageName ModuleRenaming))] -> Component -> ([(UnitId, PackageId)], Map PackageName ModuleRenaming)
|
|
|
|
otherDeps deps comp = fromMaybe ([], M.empty) $
|
2015-02-04 00:12:51 +00:00
|
|
|
flip lookup deps =<< read <$> lookup "x-build-depends-like" fields
|
|
|
|
where
|
|
|
|
fields = customFieldsBI (componentBuildInfo comp)
|
2017-05-17 21:59:29 +00:00
|
|
|
|
|
|
|
setComponentPackageRenaming clbi cprn =
|
|
|
|
clbi { componentPackageRenaming =
|
|
|
|
componentPackageRenaming clbi `M.union` cprn }
|
|
|
|
|
|
|
|
-- setUnionDeps :: ([(UnitId, PackageId)], Map PackageName ModuleRenaming) -> ComponentLocalBuildInfo -> ComponentLocalBuildInfo
|
|
|
|
setUnionDeps (deps, rns) clbi = let
|
|
|
|
clbi' = setComponentPackageRenaming clbi rns
|
|
|
|
cpdeps = componentPackageDeps clbi
|
|
|
|
in
|
|
|
|
clbi' {
|
|
|
|
componentPackageDeps = cpdeps `union` deps
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
-- 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 isInternal (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
|
|
|
|
|
|
|
|
when (exeName exe == "ghc-mod-real") $ do
|
|
|
|
createDirectoryIfMissingVerbose verbosity True libexecdir
|
|
|
|
renameFile fixedExeFileName newExeFileName
|
|
|
|
|
|
|
|
fn pd_regular lbi
|
|
|
|
|
|
|
|
where
|
|
|
|
isInternal :: Executable -> Bool
|
|
|
|
isInternal exe =
|
|
|
|
fromMaybe False $ (=="True") <$> lookup "x-internal" (customFieldsBI $ buildInfo exe)
|
|
|
|
|
|
|
|
onlyExePackageDesc :: [Executable] -> PackageDescription -> PackageDescription
|
|
|
|
onlyExePackageDesc exes pd = emptyPackageDescription {
|
|
|
|
package = package pd
|
|
|
|
, executables = exes
|
|
|
|
}
|