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!
When you run cabal install multithreaded (-j2 and up), single file compilation does not appear on stdout, but should still be written to the log file.
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!
Related
I'm trying to build my project and I'm running into a really strange problem. I got my friend to install Haskell with Chocolatey and when he goes to compile my project with cabal build and cabal run project he runs into the following error that I just don't have:
Expr.hs:103:1: error:
Type applications in patterns are not yet supported
|
103 | evalVal env val #(HInteger _) = return $ val
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I assumed that the cabal file would take care of dependencies but obviously not. A cursory search as well proves fruitless because I can't even find another instance of someone having the same error.
I'm not sure if the problem is due to him being on ghc 9.0.1 and cabal 3.4 and I'm on ghc 8.8.3 and cabal 3.2 or if it's due to different operating systems, his being Windows and I OSX.
My worry is that if I upgrade my ghc and cabal versions then I will run into this error and I'll have to reinstall everything which was messy and difficult the first time
It turns out that was a change in GHC 9.0: Whitespace-sensitive !, ~, #, and $
it's the second point there:
f # x = y
Before: value binding that binds both f and x to y using an as-pattern
After: infix function named (#)
To restore the old behavior, remove the leading and trailing whitespace around #, like so:
f#x = x
So if you change it to
evalVal env val#(HInteger _) = return $ val
it should work for both compilers
When I tried to run cabal benchmark on bytestring I got package has no benchmark. Indeed, the .cabal file does not have benchmark configs. But the repo does have a bench directory. How does this work? Should I not try to benchmark it?
edit:
When running cabal build in the bench directory I got the following error:
Building bench-bytestring-0.1.0.0...
Preprocessing executable 'bench-bytestring-builder' for
bench-bytestring-0.1.0.0...
[18 of 18] Compiling Main ( BenchAll.hs, dist/build/bench-bytestring-builder/bench-bytestring-builder-tmp/Main.o )
BenchAll.hs:133:46:
Couldn't match expected type ‘Benchmarkable’
with actual type ‘IO ()’
In the second argument of ‘($)’, namely ‘benchIntEncodingB nRepl e’
In the expression:
bench (name ++ " (" ++ show nRepl ++ ")")
$ benchIntEncodingB nRepl e
The bench directory has a separate Cabal file, bench-bytestring.cabal. You should be able to cd into that directory and do cabal run to run the benchmarks.
That package's description explains why it works this way:
This package is not meant for public release. It fixes a problem with the current benchmarking support in cabal, which has trouble compiling because criterion depends on bytestring. Here, we just include the whole source of the bytestring library directly.
I've set up my environment as instructed in quick start guide (http://www.yesodweb.com/page/quickstart) without any obvious troubles on my 64bit Window 7 machine.
I then run the following (which execute fine)
"yesod init"
"cabal install --enable-tests --reorder-goals --max-backjumps=-1 -j"
However when I run "yesod devel" I find it stuck (not doing anything) showing following message:
> yesod devel
Yesod devel server. Press ENTER to quit
yesod: DeleteFile "C:\\Users\\USER~1\\AppData\\Local\\Temp\\10445.o": does
not exist (The system cannot find the file specified.)
Mentioned temp file does not exist in the Temp folder.
I tried looking at yesod source code to see what it does but not sure if that helps:
putStrLn $ "Yesod devel server. " ++ terminator ++ " to quit"
void $ forkIO $ do
filesModified <- newEmptyMVar
void $ forkIO $
void $ watchTree manager "." (const True) (\_ -> void (tryPutMVar filesModified ()))
evalStateT (mainOuterLoop develHsPath iappPort filesModified) Map.empty
after
writeLock opts
exitSuccess
I had the same issue as yours and I've even reported it: https://github.com/yesodweb/yesod/issues/949
The problem gone after flushing the cabal package cache and rebuilding everything from scratch. This is definitely an environmental issue.
Also if you're experiencing anything like this, be sure to check PATH if there are some 3rd-party gcc installations in it.
I've installed Leksah 0.12.1.3 on Xubuntu 13.10 from terminal.
sudo apt-get install leksah
Opened leksah, created new workspace and package.
Main.hs is created by default with 'Hello world' program.
module Main (
main
) where
import Control.Monad (unless)
import Data.List (stripPrefix)
import System.Exit (exitFailure)
import Test.QuickCheck.All (quickCheckAll)
-- Simple function to create a hello message.
hello s = "Hello " ++ s
-- Tell QuickCheck that if you strip "Hello " from the start of
-- hello s you will be left with s (for any s).
prop_hello s = stripPrefix "Hello " (hello s) == Just s
-- Hello World
exeMain = do
putStrLn (hello "World")
-- Entry point for unit tests.
testMain = do
allPass <- $quickCheckAll -- Run QuickCheck on all prop_ functions
unless allPass exitFailure
-- This is a clunky, but portable, way to use the same Main module file
-- for both an application and for unit tests.
-- MAIN_FUNCTION is preprocessor macro set to exeMain or testMain.
-- That way we can use the same file for both an application and for tests.
#ifndef MAIN_FUNCTION
#define MAIN_FUNCTION exeMain
#endif
main = MAIN_FUNCTION
Now, if I try to run package, or write anything in editor, in lower-right window
========== 127 ==========================
appears.
This happens to me a lot.... I don't know what the cause is, but (at least in my case) I know I can fix the problem by just using the command line. I just "cd" into the directory with the package (the one with the *.cabal file), and type
cabal configure
cabal build
after this is done, Leksah works properly. Clearly it is a Leksah bug, but it is easy to work around.
Problem was in my naive assumption that 'apt-get install leksah' will install all needed packages.
However, that's not correct.
After leksah installation you'll need:
apt-get install cabal-install
apt-get install ghc
cabal update
After that, as jamshidh mentioned, you need to click package->cofigure.
Now build brakes with (for program posted in question, which is leksah autogenerated default):
Couldn't match type `IO' with `[]'
Expected type: String
Actual type: IO ()
In the first argument of `putStrLn', namely `testMain'
In the expression: putStrLn testMain
In an equation for `main': main = putStrLn testMain
But I managed to build much simpler version:
module Main (
main
) where
main = putStrLn "Hello World"
The problem with the default hello world is the following line:
putStrLn (hello "World")
It's simply that the left quote is not in the correct place. Change that to
putStrLn ("hello World")
and it should work.
What's the best way to iterate over all the modules (files) in a given package? Concretely, suppose I have
an executable called "runThis"
a cabal package P with files F1.hs, F2.hs, ..., Fn.hs
Whats the easiest way to execute:
runThis F1.hs
runThis F2.hs
...
runThis Fn.hs
?
I thought I might try --with-compiler but that fails with
cabal: The program ghc version >=6.4 is required but the version of runThis
(The other option looks like tweaking the Setup.lhs -- but ideally I'd like to hijack the build process and use "runThis" instead of, say, ghc)
Thanks!
From Duncan Coutts' email:
Question: How to add the preprocessor? I have tried
main =
defaultMainWithHooks
simpleUserHooks{hookedPreProcessors=[("foo",transformation)]}
transformation :: BuildInfo -> LocalBuildInfo -> PreProcessor
That looks right. Here's how to complete it (example taken from the
Cabal haddock docs for the PreProcess module):
transformation _ _ =
PreProcessor {
platformIndependent = True,
runPreProcessor =
mkSimplePreProcessor $ \inFile outFile verbosity -> do
fail $ "transformation: " ++ inFile ++ " " ++ outFile
}
and it works fine:
runghc Setup.hs build
Preprocessing library foo-1.0...
Setup.hs: transformation: Abc.foo dist/build/Abc.hs
But under which circumstances will this function be called? Up to now
I have not succeeded in making cabal call this function.
It calls it when it goes and looks for the module Abc (ie Abc.hs
or .lhs), and since if does not find it, it'll check through the list of
preprocessors and go looking for the corresponding files, ie Abc.foo.