Search code examples
haskellconfigurationghccabalcabal-install

Progress messages not appearing with cabal install for some users


I'm working on a team project using Haskell and whenever I compile our project using 'cabal install' I start seeing the following:

$ cabal clean && cabal install
cleaning...
Resolving dependencies...
Configuring hackathon-0.1...
Building hackathon-0.1...
Preprocessing executable 'hackathon' for hackathon-0.1...
[ 1 of 65] Compiling Data.MaybeUtil   ( src/Data/MaybeUtil.hs, dist/dist-sandbox-52369b17/build/hackathon/hackathon-tmp/Data/MaybeUtil.o )
[ 2 of 65] Compiling Data.JQL         ( src/Data/JQL.hs, dist/dist-sandbox-52369b17/build/hackathon/hackathon-tmp/Data/JQL.o )
[ 3 of 65] Compiling Data.Tuples      ( src/Data/Tuples.hs, dist/dist-sandbox-52369b17/build/hackathon/hackathon-tmp/Data/Tuples.o )
...
$

However, my team members see:

$ cabal clean && cabal install
cleaning...
Resolving dependencies...
Configuring hackathon-0.1...
Building hackathon-0.1...
Installed hackathon-0.1

What is different in their configuration that they don't see all of the "Progress" messages that start with [X of N] My.Module?

I would really like them to be able to see the progress of the compilation as it is happening as our project is quite large and currently has 65 modules and growing. Cheers!


Solution

  • Okay, I decided to just look at the source code and answer my own question. After diving through the cabal-install source code and ending up inside the GHC source I eventually found what I was looking for at the bottom of compiler/main/HscMain.hs:

    showModuleIndex :: (Int, Int) -> String
    showModuleIndex (i,n) = "[" ++ padded ++ " of " ++ n_str ++ "] "
      where
        n_str = show n
        i_str = show i
        padded = replicate (length n_str - length i_str) ' ' ++ i_str
    

    This is the method that prints the Module Index. It is used inside a function called batchMsg which wraps it with a method called compilationProgressMessage:

    compilationProgressMsg :: DynFlags -> String -> IO ()
    compilationProgressMsg dflags msg
      = ifVerbose dflags 1 $
        logOutput dflags defaultUserStyle (text msg)
    

    As you can see this method only prints things to the log output filestream if the verbosity is one or higher.

    So I have just tried to do this in my terminal:

    cabal install -j4 -v1
    

    And then if I tail -f the .cabal-sandbox/logs/package-name.log file then I can see the module indexed compilation messages happening. I think that this solves this problem. Then, when the compilation finishes (or errors out) all of the module messages get printed to stdout. It seems that something is blocking print calls to stdout in parallel compilation in GHC. There is also something that sets the verbosity to 0 when you turn on parallel compilation. I think that both of these are bugs and should be fixed so I may go and try and raise feature requests now.

    At any rate I hope that this investigation helps somebody else too. Cheers and thanks for the pointers everybody!