-- This file is part of Qtah. -- -- Copyright 2015-2020 The Qtah Authors. -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU Lesser General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public License -- along with this program. If not, see . {-# OPTIONS_GHC -W -fwarn-incomplete-patterns -fwarn-unused-do-bind #-} {-# LANGUAGE CPP, RankNTypes #-} import Control.Monad (unless, when) import Distribution.PackageDescription (PackageDescription) import Distribution.Simple (defaultMainWithHooks, simpleUserHooks) import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo, absoluteInstallDirs, bindir, pkgDescrFile, withPrograms, ) import Distribution.Simple.Program (Program, runDbProgram, simpleProgram) import Distribution.Simple.Setup ( ConfigFlags, CleanFlags, CopyDest (CopyTo, NoCopyDest), cleanVerbosity, configVerbosity, copyDest, #if MIN_VERSION_Cabal(2,0,0) copyVerbosity, #endif flagToMaybe, fromFlagOrDefault, installDistPref, #if MIN_VERSION_Cabal(2,0,0) installVerbosity, #endif ) import Distribution.Simple.UserHooks ( UserHooks ( cleanHook, copyHook, hookedPrograms, instHook, postConf ), ) #if MIN_VERSION_Cabal(2,0,0) import Distribution.Simple.Utils (die') #else import Distribution.Simple.Utils (die) #endif import Distribution.Simple.Utils (info, installExecutableFile) import Distribution.Verbosity (normal, verbose) import System.Directory ( createDirectoryIfMissing, doesFileExist, executable, getCurrentDirectory, getPermissions, removeFile, setOwnerExecutable, setPermissions, ) import System.FilePath ((), joinPath, takeDirectory) type DieFn = forall a. String -> IO a main :: IO () main = defaultMainWithHooks qtahHooks qtahHooks :: UserHooks qtahHooks = simpleUserHooks { hookedPrograms = [bashProgram] , postConf = \_ cf _ lbi -> generateSources cf lbi , copyHook = \pd lbi uh cf -> do let dest = fromFlagOrDefault NoCopyDest $ copyDest cf doInstall pd lbi dest #if MIN_VERSION_Cabal(2,0,0) (die' $ fromFlagOrDefault normal $ copyVerbosity cf) #else die #endif copyHook simpleUserHooks pd lbi uh cf , instHook = \pd lbi uh if' -> do let dest = maybe NoCopyDest CopyTo $ flagToMaybe $ installDistPref if' doInstall pd lbi dest #if MIN_VERSION_Cabal(2,0,0) (die' $ fromFlagOrDefault normal $ installVerbosity if') #else die #endif instHook simpleUserHooks pd lbi uh if' , cleanHook = \pd z uh cf -> do doClean cf cleanHook simpleUserHooks pd z uh cf } bashProgram :: Program bashProgram = simpleProgram "bash" findProjectRootDir :: LocalBuildInfo -> DieFn -> IO FilePath findProjectRootDir localBuildInfo dieFn = case pkgDescrFile localBuildInfo of Just path -> return $ takeDirectory path Nothing -> dieFn "Couldn't find the project root path." generateSources :: ConfigFlags -> LocalBuildInfo -> IO () generateSources configFlags localBuildInfo = do -- Generate binding sources for the generated C++ listener classes. let verbosity = fromFlagOrDefault normal $ configVerbosity configFlags projectRootDir <- findProjectRootDir localBuildInfo #if MIN_VERSION_Cabal(2,0,0) (die' verbosity) #else die #endif let genPath = projectRootDir "qtah-listener-gen" programDb = withPrograms localBuildInfo -- Cabal 1.24 (GHC 8?) seems to remove the executable bit from -- qtah-listener-gen before configuring, so we have to re-add it. -- -- See: https://github.com/haskell/cabal/issues/4170 perms <- getPermissions genPath unless (executable perms) $ setPermissions genPath $ setOwnerExecutable True perms runDbProgram verbosity bashProgram programDb [genPath, "--gen-hs-dir", "."] doInstall :: PackageDescription -> LocalBuildInfo -> CopyDest -> DieFn -> IO () doInstall packageDesc localBuildInfo copyDest dieFn = do projectRootDir <- findProjectRootDir localBuildInfo dieFn let binDir = bindir $ absoluteInstallDirs packageDesc localBuildInfo copyDest createDirectoryIfMissing True binDir installExecutableFile verbose (projectRootDir "qtah-listener-gen") (binDir "qtah-listener-gen") doClean :: CleanFlags -> IO () doClean cleanFlags = do startDir <- getCurrentDirectory let interfaceDir = startDir joinPath ["src", "Graphics", "UI", "Qtah", "Generator", "Interface"] delFile $ interfaceDir "Listener.hs" delFile $ interfaceDir "Listener.hs-boot" where verbosity = fromFlagOrDefault normal $ cleanVerbosity cleanFlags delFile path = do exists <- doesFileExist path when exists $ do info verbosity $ concat ["Removing file ", path, "."] removeFile path