GHC warnings are suppressed unless intermediate files are deleted - haskell

I'm compiling my program as: ghc -Wall foo.hs
and I get some helpful warnings:
foo.hs:14:1: Warning:
Top-level binding with no type signature: main :: IO ()
Now, if I immediately re-run ghc -Wall foo.hs, I get no warnings. If I delete the intermediate files foo.o and foo.hi, then run ghc -Wall foo.hs, the warnings reappear.
Is this intended behaviour? Can I make it so warnings are always displayed without having to delete intermediate files?

If the results of compilation (.hi and .o) already exist then GHC will not recompile the .hs. GHC only emits the warning when it compiles (or typechecks) the .hs.
Perhaps you could use ghc -fforce-recomp foo.hs to force recompiling. (If you just want to typecheck then it's quicker to useghc -fforce-recomp -fno-code foo.hs but there are some warnings that -fno-code doesn't catch.)

Related

How do I disable `-Werror` only when compiling as a library?

I have
ghc-options:
- -Wall
- -Werror
in my package.yaml and it builds fine for GHC 8.6.
But when using the project in a GHC 9 codebase, it errors because of an unnessessary MonadFail import.
How can I change the library such that it won't abort compilation when used in other projects?
I have tried
ghc-options:
"$everything": -Wwarn
in the downstream (dependent) project, but that doesn't seem to affect it. I expected -Wwarn to override the -Werror since $everything should cover even dependencies.
I believe, it is bad practice to specify -Werror on the library itself. Same goes for other compiler flags, such as optimization for example -O2.
Setting -Wall on the other hand is definitely good stuff, plus a few other warning flags of top of my head, eg. -Wincomplete-record-updates, -Wincomplete-uni-patterns, -Wredundant-constraints, etc.
If you want to turn build warnings into errors while working on the library or in CI, which is a sensible thing to do, then you can enable it in your
stack.yaml:
ghc-options:
my-library: -Werror
cabal.project:
package my-library
ghc-options: -Werror
That being said you can turn off -Werror for any library downstream by setting -Wwarn for that library in the exact same fashion as above, which will override the original flag.

GHC: ghc gives clang error, but ghc --make works

Long story short: I have two .hs files, where Main.hs uses module Lib.hs
When I try to compile them as suggested by the book Real World Haskell, p 115, I got problems:
$ ghc -c Lib.hs
$ ghc -o main Main.hs Lib.o
[2 of 2] Compiling Main ( Main.hs, Main.o )
Linking main ...
duplicate symbol '_Lib_add1_info' in:
./Lib.o
Lib.o
duplicate symbol '_Lib_add1_closure' in:
./Lib.o
Lib.o
ld: 3 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
`clang' failed in phase `Linker'. (Exit code: 1)
But, when I simply use ghc --make, it works fine
$ ghc --make Main.hs
[1 of 2] Compiling Lib ( Lib.hs, Lib.o )
[2 of 2] Compiling Main ( Main.hs, Main.o )
Linking Main ...
$ ls -1
Lib.hi
Lib.hs
Lib.o
Main
Main.hi
Main.hs
Main.o
Can anyone explain why ghc --make works while simply ghc does not?
BTW, my ghc's version is
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.5
From the GHC docs:
--make
In this mode, GHC will build a multi-module Haskell program automatically, figuring out dependencies for itself. If you have a
straightforward Haskell program, this is likely to be much easier, and
faster, than using make. [..]
This mode is the default if there are any Haskell source files mentioned on the command line, and in this case the --make option can
be omitted.
Hence your line
ghc -o main Main.hs Lib.o
actually means
ghc -o main --make Main.hs Lib.o
which will compile and link Main.hs and all its dependencies (including Lib.o), adding another Lib.o during linking. This will link Lib.o twice, triggering the linker error reported by the OP.
I guess this was changed in GHC after Real World Haskell was written.

Setting cabal configuration options in a stack project

In my stack project I have a myproject.cabal file. I would like to try the cabal option --disable-library-profiling documented here:
https://www.haskell.org/cabal/users-guide/installing-packages.html
However, I've been unable to figure out where that option must be used: wherever I put it, subsequent stack runs exit with failure (complaining in one way or another about the option).
My higher-level goal is to see if this speeds up ghc compilation for my project, but that's really secondary as far as this question goes: I'd really just like to know how these configuration options work (in the context of stack projects).
I'm using ghc 6.7. In particular, if I use cabal configure, the option ends up configured in ghc-options in my myproject.cabal file, but GHC then complains:
ghc: unrecognised flag: --disable-library-profiling
I'm already using other ghc-options without running into similar trouble -- stack completes successfully in this case:
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O0 -j +RTS -A128m -n2m -RTS
but not in this case:
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O0 -j +RTS -A128m -n2m -RTS --disable-library-profiling
The stack equivalent of --disable-library-profiling is:
$ stack build --no-library-profiling

GHC 7.8.3 not producing binary

No binary is produced when I ghc -O2 --make Test.hs, but only the .o and .hi files.
Test.hs contains a main :: IO () function and has module name Test.
Is the linker not behaving? How can I fix this?
I'm using GHC 7.8.3 on OSX, have Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) Target: x86_64-apple-darwin13.4.0
Thank you in advance for any hints
Your problem is the module name. GHC expects a function named main in a module named Main as a default. You can override this with the -main-is option. As in
ghc -O2 -main-is Test --make Test.hs

Problem Specifying Source Directory to GHC

This is an embarrassingly simple problem, but its solution yet eludes me. As the title indicates, I simply want to specify to GHC the location of all my source files. This should be simple; the GHC user guide:
-idirs
This flag appends a colon-separated
list of dirs to the search path.
So, I tried the following invocations:
ghc -isrc/ -v -outputdir build/ --make -Wall Main.hs
ghc -isrc/: -v -outputdir build/ --make -Wall Main.hs
ghc -i:src/: -v -outputdir build/ --make -Wall Main.hs
ghc -i"src/" -v -outputdir build/ --make -Wall Main.hs
ghc -i"src/": -v -outputdir build/ --make -Wall Main.hs
ghc -i:"src/": -v -outputdir build/ --make -Wall Main.hs
On every invocation GHC gave the error: "<no location info>: can't find file: Main.hs"
As you probably could have guessed, Main.hs is located in a subdirectory from the working directory called "src". Just in case it matters, I'm on Windows XP, and I'm using GHC 6.12.2. I'm assuming there is some small problem that I'm just missing.
-i specifies where GHC will search for other source files, other than the ones you specify on the command line. So your Main.hs there will also need a src/ prefix. E.g.
$ ghc -isrc src/Main.hs --make
[1 of 1] Compiling Main ( src/Main.hs, src/Main.o )
Linking src/Main ...
Alternatively, you could use cabal, and have cabal init generate all the build metadata for you.

Resources