From 49e6f314e89177b18242736cd557e792b808fa2f Mon Sep 17 00:00:00 2001 From: sheaf Date: Thu, 28 Sep 2023 17:20:15 +0200 Subject: [PATCH] first pass at preBuild SetupHooks --- Cabal/src/Distribution/Simple.hs | 35 ++++++++++----- Cabal/src/Distribution/Simple/Build.hs | 22 +++++++-- Cabal/src/Distribution/Simple/Configure.hs | 8 ++-- Cabal/src/Distribution/Simple/SetupHooks.hs | 50 ++++++++++++++------- 4 files changed, 81 insertions(+), 34 deletions(-) diff --git a/Cabal/src/Distribution/Simple.hs b/Cabal/src/Distribution/Simple.hs index a2ff758d6e5..1e6447a5599 100644 --- a/Cabal/src/Distribution/Simple.hs +++ b/Cabal/src/Distribution/Simple.hs @@ -105,7 +105,7 @@ import Distribution.Simple.Haddock import Distribution.Simple.Install import Distribution.Simple.LocalBuildInfo import Distribution.Simple.SetupHooks - ( SetupHooks(..), simpleSetupHooks + ( SetupHooks, simpleSetupHooks , applyPackagePreConfDiff ) import qualified Distribution.Simple.SetupHooks as SetupHooks @@ -156,15 +156,29 @@ defaultMainWithSetupHooks setup_hooks = defaultMainWithSetupHooksArgs :: SetupHooks -> [String] -> IO () defaultMainWithSetupHooksArgs setup_hooks = - defaultMainHelper setup_hooks (simpleUserHooks { confHook = setup_confHook }) + defaultMainHelper setup_hooks $ + simpleUserHooks + { confHook = setup_confHook + , buildHook = setup_buildHook + } where - setup_confHook - :: (GenericPackageDescription, HookedBuildInfo) - -> ConfigFlags - -> IO LocalBuildInfo - setup_confHook = - configure_maybeSetupHooks (preConfComponent setup_hooks) + setup_confHook + :: (GenericPackageDescription, HookedBuildInfo) + -> ConfigFlags + -> IO LocalBuildInfo + setup_confHook = + configure_mbSetupHooks (SetupHooks.preConfComponent setup_hooks) + + setup_buildHook + :: PackageDescription + -> LocalBuildInfo + -> UserHooks + -> BuildFlags + -> IO () + setup_buildHook pkg_descr lbi hooks flags = + build_mbSetupHooks (SetupHooks.preBuild setup_hooks) + pkg_descr lbi flags (allSuffixHandlers hooks) -- | A customizable version of 'defaultMain'. defaultMainWithHooks :: UserHooks -> IO () @@ -270,8 +284,7 @@ configureAction setup_hooks hooks flags args = do verbosity (flagToMaybe (configCabalFilePath flags)) - mb_lbi_diff <- for (preConfPackage setup_hooks) $ \ pre_conf_package -> - pre_conf_package args + mb_lbi_diff <- for (SetupHooks.preConfPackage setup_hooks) ($ args) let epkg_descr = (pkg_descr0, pbi) @@ -828,7 +841,7 @@ simpleUserHooks = verbosity = fromFlag (configVerbosity flags) autoconfSetupHooks :: SetupHooks -autoconfSetupHooks = simpleSetupHooks { preConfComponent = Just $ pre_conf } +autoconfSetupHooks = simpleSetupHooks { SetupHooks.preConfComponent = Just $ pre_conf } where pre_conf :: SetupHooks.ConfigEnv diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 161795a126c..02b2adf350b 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -18,7 +18,7 @@ -- compiler-specific actions. It does do some non-compiler specific bits like -- running pre-processors. module Distribution.Simple.Build - ( build + ( build, build_mbSetupHooks , repl , startInterpreter , initialBuildSteps @@ -77,6 +77,7 @@ import Distribution.Simple.Program.Builtin (haskellSuiteProgram) import qualified Distribution.Simple.Program.GHC as GHC import Distribution.Simple.Program.Types import Distribution.Simple.Register +import Distribution.Simple.SetupHooks ( PreBuildHook ) import Distribution.Simple.Setup.Build import Distribution.Simple.Setup.Config import Distribution.Simple.Setup.Repl @@ -111,7 +112,20 @@ build -> [PPSuffixHandler] -- ^ preprocessors to run before compiling -> IO () -build pkg_descr lbi flags suffixes = do +build = build_mbSetupHooks Nothing + +build_mbSetupHooks + :: Maybe PreBuildHook + -> PackageDescription + -- ^ Mostly information from the .cabal file + -> LocalBuildInfo + -- ^ Configuration information + -> BuildFlags + -- ^ Flags that the user passed to build + -> [PPSuffixHandler] + -- ^ preprocessors to run before compiling + -> IO () +build_mbSetupHooks mb_preBuildHook pkg_descr lbi flags suffixes = do -- Currently here checkSemaphoreSupport verbosity (compiler lbi) flags targets <- readTargetInfos verbosity pkg_descr lbi (buildArgs flags) @@ -136,11 +150,11 @@ build pkg_descr lbi flags suffixes = do -- dumped. dumpBuildInfo verbosity distPref (configDumpBuildInfo (configFlags lbi)) pkg_descr lbi flags - -- Now do the actual building (\f -> foldM_ f (installedPkgs lbi) componentsToBuild) $ \index target -> do - -- SetupHooks TODO: hook here for preBuild let comp = targetComponent target clbi = targetCLBI target + for_ mb_preBuildHook $ \ preBuild_hook -> + preBuild_hook lbi comp componentInitialBuildSteps distPref pkg_descr lbi clbi verbosity let bi = componentBuildInfo comp progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi) diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 4354f415ff3..15c92e62ea9 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -29,7 +29,7 @@ -- the user, the amount of information displayed depending on the verbosity -- level. module Distribution.Simple.Configure - ( configure, configure_maybeSetupHooks + ( configure, configure_mbSetupHooks , writePersistBuildConfig , getConfigStateFile , getPersistBuildConfig @@ -411,14 +411,14 @@ configure :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo -configure = configure_maybeSetupHooks Nothing +configure = configure_mbSetupHooks Nothing -configure_maybeSetupHooks +configure_mbSetupHooks :: Maybe PreConfComponentHook -> (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo -configure_maybeSetupHooks mb_preConfComponentHook (pkg_descr0, pbi) cfg = do +configure_mbSetupHooks mb_preConfComponentHook (pkg_descr0, pbi) cfg = do -- Determine the component we are configuring, if a user specified -- one on the command line. We use a fake, flattened version of -- the package since at this point, we're not really sure what diff --git a/Cabal/src/Distribution/Simple/SetupHooks.hs b/Cabal/src/Distribution/Simple/SetupHooks.hs index 3f570565553..40b64ab3d7d 100644 --- a/Cabal/src/Distribution/Simple/SetupHooks.hs +++ b/Cabal/src/Distribution/Simple/SetupHooks.hs @@ -16,9 +16,11 @@ module Distribution.Simple.SetupHooks , TestSuiteDiff, BenchmarkDiff , BuildInfoDiff , applyComponentDiffs - -- *** HookedBuildInfo compatibility code , hookedBuildInfoComponents, hookedBuildInfoComponentDiff_maybe + + -- * Build setup hooks + , PreBuildHook ) where @@ -51,19 +53,14 @@ import System.FilePath (takeDirectory, ()) -- SetupHooks type Args2 = [String] -- SetupHooks TODO -type PreConfPackageHook = Args2 -> IO LocalBuildConfig -type PreConfComponentHook = ConfigEnv -> IO ( Set ComponentName - , Component -> IO ComponentDiff) +-- SetupHooks TODO: document this datatype and its fields. data SetupHooks = SetupHooks { preConfPackage :: Maybe PreConfPackageHook , preConfComponent :: Maybe PreConfComponentHook - --, preBuild - -- For pre-build: hook can declare list of dependencies - -- to know when it needs to re-run the pre-build hook. - -- SetupHooks TODO: see how cabal handles recompilation logic. + , preBuild :: Maybe PreBuildHook --, hookedPrograms -- SetupHooks TODO: hooked programs (see nix-paths?). @@ -73,10 +70,24 @@ simpleSetupHooks :: SetupHooks simpleSetupHooks = SetupHooks { preConfPackage = Nothing , preConfComponent = Nothing + , preBuild = Nothing } -------------------------------------------------------------------------------- -- Per-package configure hook. + +type PreConfPackageHook = Args2 -> IO LocalBuildConfig + +applyPackagePreConfDiff :: LocalBuildConfig -> LocalBuildInfo -> IO LocalBuildInfo +applyPackagePreConfDiff cfg_diff lbi@(NewLocalBuildInfo { localBuildConfig = cfg0 }) + = return $ lbi { localBuildConfig = cfg0 <> cfg_diff } + +-------------------------------------------------------------------------------- +-- Per-component configure hook. + +type PreConfComponentHook = ConfigEnv -> IO ( Set ComponentName + , Component -> IO ComponentDiff ) + data ConfigEnv = ConfigEnv { configFlags :: ConfigFlags @@ -84,6 +95,9 @@ data ConfigEnv , flagAssignment :: FlagAssignment , hostPlatform :: Platform } + -- SetupHooks TODO: these are the fields needed to implement the Configure + -- build-type using SetupHooks. We might want to pass more information + -- to the per-component configure hook. configEnvBuildDir :: ConfigEnv -> FilePath configEnvBuildDir (ConfigEnv { configFlags = cfg }) @@ -103,13 +117,6 @@ configEnvBaseDir cfg_env = "" (takeDirectory <$> configEnvCabalFilePath cfg_env) -applyPackagePreConfDiff :: LocalBuildConfig -> LocalBuildInfo -> IO LocalBuildInfo -applyPackagePreConfDiff cfg_diff lbi@(NewLocalBuildInfo { localBuildConfig = cfg0 }) - = return $ lbi { localBuildConfig = cfg0 <> cfg_diff } - --------------------------------------------------------------------------------- --- Per-component configure hook. - type LibraryDiff = Library type ForeignLibDiff = ForeignLib type ExecutableDiff = Executable @@ -385,3 +392,16 @@ buildInfoLibraryDiff bi = emptyLibrary { libBuildInfo = bi } buildInfoExecutableDiff :: BuildInfo -> ExecutableDiff buildInfoExecutableDiff bi = emptyExecutable { buildInfo = bi } + +-------------------------------------------------------------------------------- +-- Build setup hooks. + +type PreBuildHook = LocalBuildInfo -> Component -> IO () + +-- SetupHooks TODO: introduce some kind of recompilation logic +-- that allows the hook to declare a list of dependencies which is then +-- used in Cabal to decide when it needs to re-run the build hooks. +-- +-- To do this, we should look at how cabal handles recompilation logic. + +--------------------------------------------------------------------------------