GHC compilation bug? - haskell

Some time ago I devised a little system to make compilation and testing of my Haskell programs a bit more comfortable. My project root looks as follows:
./bin/
./bin/myMain
./bin/test
./interfaces/
./obj/
./src/
./src/makefile
./src/MyLib.hs
./src/myMain.hs
./src/testSuite.hs
myMain is the main module, whose imports are like those:
import MyLib
-- irrelevant content follows
testSuite is similar:
import System.Exit
import Test.HUnit
import MyLib
-- irrelevant content follows
I compile those with two simple commands:
ghc testSuite.hs -o ../bin/test -odir ../obj -hidir ../interfaces
ghc myMain.hs -o ../bin/myMain -odir ../obj -hidir ../interfaces
Now, as I run the first, whole test suite compiles and executes perfectly fine, even if there are any object or intereface files present. However when I run the second to compile main executable, it compiles test binary again unless I run remove object and interface files.
The reason is, as far as I found, that main module produces Main.o and Main.hi, no matter what its name is. Therefore while compiling myMain, GHC sees those files present, so does not recompile main module. The strange part is this is not the case when I compile test suite - in such a case Main is recompiled even if there are objects and interfaces present.
$ ghc testSuite.hs -o ../bin/test -odir ../obj -hidir ../interfaces
[1 of 2] Compiling MyLib ( MyLib.hs, ../obj/MyLib.o )
[2 of 2] Compiling Main ( testSuite.hs, ../obj/Main.o )
Linking ../bin/test ...
$ ghc myMain.hs -o ../bin/myMain -odir ../obj -hidir ../interfaces
Linking ../bin/myMain ...
But when I run main compilation first:
$ ghc myMain.hs -o ../bin/myMain -odir ../obj -hidir ../interfaces
[1 of 2] Compiling MyLib ( MyLib.hs, ../obj/MyLib.o )
[2 of 2] Compiling Main ( myMain.hs, ../obj/Main.o )
Linking ../bin/myMain ...
$ ghc testSuite.hs -o ../bin/test -odir ../obj -hidir ../interfaces
[2 of 2] Compiling Main ( testSuite.hs, ../obj/Main.o ) [Test.HUnit changed]
Linking ../bin/test ...
What's even stranger, the problem disappears when I put aside -odir and -hidir GHC parameters and compile everything in the same directory. Why?
[NOTE:]
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3

Related

GHC compiles to .o and .hi but no executable

I've been working on a small file which I've been compiling and running as I go. My directory contains Log.hs and LogAnalysis.hs.
LogAnalysis.hs looks like this:
{-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log
parseMessage :: String -> LogMessage
--some code...
main :: IO ()
main = do
putStrLn (show (parseMessage ("Some log message text")))
When I compile the LogAnalysis.hs with GHC I was getting an executable, along with some other binary files:
$ ll
Log.hi
Log.hs
Log.o
LogAnalysis <-- this is the executable which has disappeared
LogAnalysis.hi
LogAnalysis.hs
LogAnalysis.o
I made some small changes and now when I run ghc LogAnalysis.hs I get only the .hi and .o files but no executable. The output is:
[1 of 2] Compiling Log ( Log.hs, Log.o )
[2 of 2] Compiling LogAnalysis ( LogAnalysis.hs, LogAnalysis.o )
I'm not even sure what I changed, but it wasn't anything major. Any idea what could be triggering this? Is there some way to force GHC to produce an executable?
Specs: GHC 8.8.3, macOS 10.15.5
Since I was declaring the file as a module not named Main, GHC by default doesn't create an executable. In order to compile this module into an executable, we can use GHC's main-is flag. (Thanks to Krantz in the comments and Willem Van Onsem's answer here for this.) So compiling with
ghc -main-is LogAnalysis LogAnalysis.hs
gives the output
[2 of 2] Compiling LogAnalysis ( LogAnalysis.hs, LogAnalysis.o )
Linking LogAnalysis ...
So GHC has linked the executable LogAnalysis which is the desired result.
There is an easier way to fix it, delete the second line:
module LogAnalysis where
I believe that when you define it as a module, ghc understands that it is just a module that will be imported in another file so it doesn't create an executable.

Can "-main-is" ghc's option be use via OPTIONS_GHC pragma?

Given MyModule.hs
$ cat MyModule.hs
{-# OPTIONS_GHC -main-is MyModule.main #-}
module MyModule where
main = print "MyModule.Main"
I can make an executable app with -main-is options
$ ghc -o app -main-is MyModule.main MyModule.hs
[1 of 1] Compiling MyModule ( MyModule.hs, MyModule.o ) [flags changed]
Linking app ...
But when I ommit -main-is option and hope ghc will use OPTIONS_GHC pragma, it doesn't work.
$ ghc -o app MyModule.hs
[1 of 1] Compiling MyModule ( MyModule.hs, MyModule.o )
<no location info>: error:
output was redirected with -o, but no output will be generated
because there is no Main module.
The document mention -main-is as dynamic option type which mean it should be possible to use via the pragma (ref)
Question:
Can -main-is be use via OPTIONS_GHC pragma?
Did I use the pragma wrong way?

Clang error while installing QuickCheck for GHC 7.8.3 on OS X Yosemite 10.10 (14A389)

While installing the QuickCheck for Haskell GHC 7.8.3 on a OS X Yosemite 10.10 (14A389) system running on a Mac Pro 2013 with Xcode 6.1 (6A1052d), I'm running into the following clang error:
$ cabal install QuickCheck
Resolving dependencies...
Configuring primitive-0.5.4.0...
Building primitive-0.5.4.0...
Preprocessing library primitive-0.5.4.0...
[ 1 of 10] Compiling Data.Primitive.Internal.Compat ( Data/Primitive/Internal/Compat.hs, dist/build/Data/Primitive/Internal/Compat.o )
[ 2 of 10] Compiling Data.Primitive.MachDeps ( Data/Primitive/MachDeps.hs, dist/build/Data/Primitive/MachDeps.o )
[ 3 of 10] Compiling Data.Primitive.Internal.Operations ( Data/Primitive/Internal/Operations.hs, dist/build/Data/Primitive/Internal/Operations.o )
[ 4 of 10] Compiling Control.Monad.Primitive ( Control/Monad/Primitive.hs, dist/build/Control/Monad/Primitive.o )
[ 5 of 10] Compiling Data.Primitive.Types ( Data/Primitive/Types.hs, dist/build/Data/Primitive/Types.o )
[ 6 of 10] Compiling Data.Primitive.Array ( Data/Primitive/Array.hs, dist/build/Data/Primitive/Array.o )
Data/Primitive/Array.hs:32:1: Warning:
The import of ‘Control.Monad.ST’ is redundant
except perhaps to import instances from ‘Control.Monad.ST’
To import instances alone, use: import Control.Monad.ST()
[ 7 of 10] Compiling Data.Primitive.ByteArray ( Data/Primitive/ByteArray.hs, dist/build/Data/Primitive/ByteArray.o )
[ 8 of 10] Compiling Data.Primitive.Addr ( Data/Primitive/Addr.hs, dist/build/Data/Primitive/Addr.o )
[ 9 of 10] Compiling Data.Primitive ( Data/Primitive.hs, dist/build/Data/Primitive.o )
[10 of 10] Compiling Data.Primitive.MutVar ( Data/Primitive/MutVar.hs, dist/build/Data/Primitive/MutVar.o )
ld: library not found for -lgmp
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Failed to install primitive-0.5.4.0
Configuring random-1.1...
Building random-1.1...
Preprocessing library random-1.1...
[1 of 1] Compiling System.Random ( System/Random.hs, dist/build/System/Random.o )
ld: library not found for -lgmp
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Failed to install random-1.1
cabal: Error: some packages failed to install:
QuickCheck-2.7.6 depends on random-1.1 which failed to install.
primitive-0.5.4.0 failed during the building phase. The exception was:
ExitFailure 1
random-1.1 failed during the building phase. The exception was:
ExitFailure 1
tf-random-0.5 depends on random-1.1 which failed to install.
It seems that the dynamic library gmp is missing. Does somebody have found a solution to this problem?
As #MichealFox said in his comment, installing command line tools resolves this issue.
xcode-select --install
It also resolves problems with many other cabal packages depending on gmp/lgmp library.
I had the same issue (in my case compiling pandoc on a Centos 7 machine).
The gmp RPM was installed but not the gmp-devel RPM (which contains headers, linkable libraries, etc). This fixed it:
yum install gmp-devel

ghc --make module hierarchy

I'm trying to build a standalone program for the first time in Haskell, and am having trouble figuring out how to get ghc --make working with the directory organization of my liking. As the moment I have the following tree:
readme.md
src/
Main.hs
Ciphers/
Affine.hs
Shift.hs
Substitution.hs
Tests/
HCTests.hs
With the following imports:
Main.hs:
module Main where
import Tests.HCTests
import Ciphers.Affine
import Ciphers.Shift
import Ciphers.Substitution
HCTests.hs
module Tests.HCTests (unitTests) where
import Ciphers.Substitution
import Ciphers.Affine
import Ciphers.Shift
Affine.hs
module Affine (
affineEnc,
affineDec,
) where
Shift.hs
module Shift (
shiftEnc,
shiftDec
) where
import Affine
Substitution.hs
module Substitution (
substitutionEnc,
substitutionDec,
) where
Based on this - https://en.wikibooks.org/wiki/Haskell/Standalone_programs - It seems to me the following command should at least properly handle the imports in main, although I'm unclear whether the imports in HCTests will work (it seems to me if I read this properly - Specifying "Up The Tree" Haskell Modules - they should).
The command, which I run in the base directory, is:
ghc -O2 --make -i src -o crypto Main.hs
Fails with error:
target `src' is not a module name or a source file
Edit
I have an additional question. Thanks to Zeta's answer, I've got that sorted, however when I run it, I get the following error:
src/Ciphers/Substitution.hs:5:8:
File name does not match module name:
Saw: `Substitution'
Expected: `Ciphers.Substitution'
So my assumption is that I'd solve this via:
Substitution.hs
module Ciphers.Substitution (
substitutionEnc,
substitutionDec,
) where
My question is how then can I handle that Shift.hs needs to import Affine.hs, while I still want both Ciphers.Shift and Ciphers.Affine?
You may not separate the command line option -i and the search path with whitespace, since -i with following whitespace resets the search path.
Use
ghc -O2 --make -isrc -o crypto Main.hs
or
ghc -O2 --make -i./src -o crypto Main.hs
instead.

Haskell GHCI not loading compiled object file

I would like GHCI to load the compiled object code for a module which when compiled is significantly faster than the none compiled version. This was working well when all of the files were in the same directory (no module hierarchies). However, they do not work when the files are in module hierarchies.
Working version MyFile.hs:
import Basic
import Histogram
where Basic.o and Histogram.o are in the same directory as MyFile.hs
Not Working version MyFile.hs:
import Util.Basic
import Util.Histogram
where Basic.o and Histogram.o are in a subdirectory Util. With this version I get the following when loading MyFile.hs:
[1 of 2] Compiling Util.Basic ( Util/Basic.hs, interpreted )
[2 of 2] Compiling Util.Histogram ( Util/Histogram.hs, interpreted )
Ok, modules loaded: Util.Basic, Util.Histogram.
I would like to be able to organize my code in modules but still receive the benefits from using the compiled o files.
Also, it should be noted that the source files have not been changed since the o files were compiled.
Edits:
Here are the contents of each file:
MyFile.hs
import Util.Basic
import Util.Histogram
Util/Basic.hs
module Util.Basic () where
Util/Histogram.hs
module Util.Histogram () where
Files / Compilation:
$:~/programming/haskell/example-error$ ls
MyFile.hs MyFile.hs~ Util
$:~/programming/haskell/example-error$ cd Util
$:~/programming/haskell/example-error/Util$ ls
Basic.hs Basic.hs~ Histogram.hs Histogram.hs~
$:~/programming/haskell/example-error/Util$ ghc *.hs
[1 of 2] Compiling Util.Histogram ( Histogram.hs, Histogram.o )
[2 of 2] Compiling Util.Basic ( Basic.hs, Basic.o )
$:~/programming/haskell/example-error/Util$ ls
Basic.hi Basic.hs~ Histogram.hi Histogram.hs~
Basic.hs Basic.o Histogram.hs Histogram.o
$:~/programming/haskell/example-error/Util$ cd ../
$:~/programming/haskell/example-error$ ghci -ignore-dot-ghci MyFile.hs
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 3] Compiling Util.Histogram ( Util/Histogram.hs, interpreted )
[2 of 3] Compiling Util.Basic ( Util/Basic.hs, interpreted )
[3 of 3] Compiling Main ( MyFile.hs, interpreted )
Ok, modules loaded: Util.Basic, Util.Histogram, Main.
*Main>
The Solution that worked as suggested by Daniel:
The fix is to compile the importing file, and the files in the
subdirectory only as a consequence of that, not directly.
The issue is the same as discussed below, the flags changed:
~/.../Util> ghc Other.hs
[1 of 1] Compiling Util.Other ( Other.hs, Other.o )
~/.../Util> cd ..
~/.../src> ghc MyFile.hs
[1 of 2] Compiling Util.Other ( Util/Other.hs, Util/Other.o ) [flags changed]
[2 of 2] Compiling MyFile ( MyFile.hs, MyFile.o )
I haven't found out which flags in particular, or why the flags passed during separate compilation are different than the ones that are passed when compiling as a module chased from the importing module, but they do change, and hence a recompilation is necessary (Specifically, the flag-hash value in the .hi file changes).
The fix is therefore to not compile the modules separately, but to compile them as dependencies of the top-level importer.
Original almost correct guesswork:
I can only partly reproduce that. After compiling and then touching MyFile.hs,
$ ghci-7.4.2 MyFile.hs
-- snip
[1 of 2] Compiling Util.Other ( Util/Other.hs, interpreted )
[2 of 2] Compiling MyFile ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.
it looks the same as for you, but with 7.6.1, we get a hint (compiling and touching):
$ ghci MyFile.hs
-- snip
[1 of 2] Compiling Util.Other ( Util/Other.hs, interpreted ) [flags changed]
[2 of 2] Compiling MyFile ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.
The flags changed. I have :set -XNoMonomorphismRestriction in my .ghci file, and the change of flags causes the recompilation.
$ ghci -ignore-dot-ghci MyFile.hs
GHCi, version 7.6.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[2 of 2] Compiling MyFile ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.
Ignoring the offending .ghci with the flag that wasn't given for the compilation, the unchanged Util.Other is not interpreted, the compiled code is used. (With GHC < 7.4, ignoring the .ghci file isn't even necessary.)
If you have a .ghci file in which you set language options (NoMonomorphismRestriction, TypeFamilies, ...) and ghc >= 7.4, you need to ignore the .ghci file when loading the modules.
If that is not the case, the recompilation is not the expected behaviour. Then more information would be necessary to diagnose the problem and find a fix.
A semi-work-around would then be the -fobject-code flag for ghci.

Resources