Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare Stack for Cabal's changing approach to hooks #6542

Open
mpilgrem opened this issue Mar 31, 2024 · 3 comments
Open

Prepare Stack for Cabal's changing approach to hooks #6542

mpilgrem opened this issue Mar 31, 2024 · 3 comments

Comments

@mpilgrem
Copy link
Member

mpilgrem commented Mar 31, 2024

Motivation:

Currently:

  • Stack itself has build type Custom, which makes use of generateBuildModule; and
  • Stack uses replHook in StackSetupShim.hs to cause Cabal to create the autogenerated files for every configured component, without building everything, before Stack uses ghc --interactive.

Related question: haskellfoundation/tech-proposals#60 (comment)

@mpilgrem
Copy link
Member Author

Currently:

Stack has:

stackReplHook :: PackageDescription -> LocalBuildInfo -> UserHooks -> ReplFlags -> [String] -> IO ()
stackReplHook pkg_descr lbi hooks flags args = do
    let distPref = fromFlag (replDistPref flags)
        verbosity = fromFlag (replVerbosity flags)
    case args of
        ("stack-initial-build-steps":rest)
            | null rest -> initialBuildSteps distPref pkg_descr lbi verbosity
            | otherwise ->
                fail "Misuse of running Setup.hs with stack-initial-build-steps, expected no arguments"
        _ -> replHook simpleUserHooks pkg_descr lbi hooks flags args

Cabal-3.10.3.0 has:

-- | Runs 'componentInitialBuildSteps' on every configured component.
initialBuildSteps ::
     FilePath -- ^"dist" prefix
  -> PackageDescription  -- ^mostly information from the .cabal file
  -> LocalBuildInfo -- ^Configuration information
  -> Verbosity -- ^The verbosity to use
  -> IO ()
initialBuildSteps distPref pkg_descr lbi verbosity =
  withAllComponentsInBuildOrder pkg_descr lbi $ \_comp clbi ->
    componentInitialBuildSteps distPref pkg_descr lbi clbi verbosity

-- | Creates the autogenerated files for a particular configured component.
componentInitialBuildSteps :: 
     FilePath -- ^"dist" prefix
  -> PackageDescription  -- ^mostly information from the .cabal file
  -> LocalBuildInfo -- ^Configuration information
  -> ComponentLocalBuildInfo
  -> Verbosity -- ^The verbosity to use
  -> IO ()
componentInitialBuildSteps _distPref pkg_descr lbi clbi verbosity = do
  createDirectoryIfMissingVerbose verbosity True (componentBuildDir lbi clbi)
  writeAutogenFiles verbosity pkg_descr lbi clbi

-- Field of UserHooks
replHook :: PackageDescription -> LocalBuildInfo -> UserHooks -> ReplFlags -> [String] -> IO ()

and, for stack --verbose ghci for a simple one-package project boo (extract, reformatted):

[info] boo> configure (lib + exe)
[debug] Run process within ...\boo\:
C:\sr\setup-exe-cache\x86_64-windows\Cabal-simple_9p6GVs8J_3.10.1.0_ghc-9.6.4.exe 
--verbose=1 
--builddir=.stack-work\dist\ab060f89
configure 
--with-ghc=...\x86_64-windows\ghc-9.6.4\bin\ghc-9.6.4.exe 
--with-ghc-pkg=...\x86_64-windows\ghc-9.6.4\bin\ghc-pkg-9.6.4.exe
--user 
--package-db=clear 
--package-db=global 
--package-db=C:\sr\snapshots\d672ac94\pkgdb 
--package-db=...\boo\.stack-work\install\fd78de5f\pkgdb 
--libdir=...\boo\.stack-work\install\fd78de5f\lib 
--bindir=...\boo\.stack-work\install\fd78de5f\bin 
--datadir=...\boo\.stack-work\install\fd78de5f\share 
--libexecdir=...\boo\.stack-work\install\fd78de5f\libexec 
--sysconfdir=...\boo\.stack-work\install\fd78de5f\etc 
--docdir=...\boo\.stack-work\install\fd78de5f\doc\boo-0.1.0.0 
--htmldir=...\boo\.stack-work\install\fd78de5f\doc\boo-0.1.0.0 
--haddockdir=...\boo\.stack-work\install\fd78de5f\doc\boo-0.1.0.0 
--dependency=base=base-4.18.2.0 
--ghc-options -haddock 
--extra-include-dirs=...\x86_64-windows\msys2-20230526\mingw64\include 
--extra-lib-dirs=...\x86_64-windows\msys2-20230526\mingw64\lib 
--extra-lib-dirs=...\x86_64-windows\msys2-20230526\mingw64\bin 
--exact-configuration 
--ghc-option=-fhide-source-paths
...
[info] boo> initial-build-steps (lib + exe)
[debug] Run process within ...\boo\: 
C:\sr\setup-exe-cache\x86_64-windows\Cabal-simple_9p6GVs8J_3.10.1.0_ghc-9.6.4.exe 
--verbose=1 
--builddir=.stack-work\dist\ab060f89 
repl 
stack-initial-build-steps <<<< This is what triggers the use of `initialBuildSteps`

@mpilgrem
Copy link
Member Author

mpilgrem commented Mar 31, 2024

An alternative to the replHook 'trick' would be for the 'setup' executable to get the information that initialBuildSteps needs. Proof of concept:

module Main (main) where

import Data.List ( stripPrefix )
import Distribution.Parsec ( eitherParsec )
import Distribution.Simple.Build ( initialBuildSteps )
import Distribution.Simple.Configure ( getPersistBuildConfig )
import Distribution.Simple.PackageDescription ( readGenericPackageDescription )
import Distribution.Simple.Utils ( findPackageDesc )
import Distribution.Types.GenericPackageDescription
         ( GenericPackageDescription (..) )
import System.Environment ( getArgs )

main :: IO ()
main = do
  args <- getArgs
  case args of
    [] -> putStrLn "Expected Cabal verbosity as first argument and builddir \
                    \as second argument."
    arg1:arg2:[] -> do
      eFp <- findPackageDesc ""
      case eFp of
        Left msg1 -> putStrLn msg1
        Right fp -> do
          let mRawVerbosity = stripPrefix "--verbose=" arg1
              mRawBuildDir = stripPrefix "--builddir=" arg2
          case (mRawVerbosity, mRawBuildDir) of
            (Nothing, _) ->
              putStrLn "Expected first argument to start --verbose="
            (_, Nothing) ->
              putStrLn "Expected second argument to start --builddir="
            (Just rawVerbosity, Just rawBuildDir) -> do
              case eitherParsec rawVerbosity of
                Left msg2 -> putStrLn msg2
                Right verbosity -> do
                  gpd <- readGenericPackageDescription verbosity fp
                  let pd = packageDescription gpd
                  lbi <- getPersistBuildConfig rawBuildDir
                  initialBuildSteps rawBuildDir pd lbi verbosity
    _ -> putStrLn "Expected only Cabal verbosity as first argument and \
                  \builddir as second argument."

@sheaf
Copy link

sheaf commented Apr 3, 2024

I believe this is incorrect for a package with Custom build-type in which the custom Setup creates autogenerated modules. Is there a reason you cannot call Setup repl here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants