Search code examples
haskellbuildcompilationcabalpost-processing

Cabal after build command (Haskell build system)


Is it possible to tell Cabal to run some command after building the application?

I want for example to generate with a script some .hs files and after building to copy some other files to dist/build/app directory.


Solution

  • Yes. Take a look at postInst and related types/operations.

    Distribution.Simple.UserHooks

    Here's a quick example, you can hoogle the relevant operations to figure out more. This executes the various .sh scripts, copies files etc. AFTER the cabal build. absoluteInstallDirs tells you where cabal is putting the other files, should you need it.

    Hope this helps!

    import Distribution.Simple
    import Distribution.Simple.LocalBuildInfo
    import System.Process
    import System.Exit
    
    main = defaultMainWithHooks fixpointHooks
    
    fixpointHooks  = simpleUserHooks { postInst = buildAndCopyFixpoint } 
    
    buildAndCopyFixpoint _ _ pkg lbi 
      = do putStrLn $ "Post Install: " ++ show binDir -- , libDir)
           executeShellCommand "./configure"
           executeShellCommand "./build.sh"
           executeShellCommand $ "chmod a+x external/fixpoint/fixpoint.native "
           executeShellCommand $ "cp external/fixpoint/fixpoint.native " ++ binDir
           executeShellCommand $ "cp external/z3/lib/libz3.* " ++ binDir
      where 
        allDirs     = absoluteInstallDirs pkg lbi NoCopyDest
        binDir      = bindir allDirs ++ "/"
    
    executeShellCommand cmd   = putStrLn ("EXEC: " ++ cmd) >> system cmd >>= check
      where 
        check (ExitSuccess)   = return ()
        check (ExitFailure n) = error $ "cmd: " ++ cmd ++ " failure code " ++ show n
    fixpointHooks  = simpleUserHooks { postInst = buildAndCopyFixpoint }