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

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.

Related

GHC warnings are suppressed unless intermediate files are deleted

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.)

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

Unable to build Haskell project with options -staticlib and -threaded on OSX

I'm having trouble building my Haskell library with GHC 7.8.2 and Cabal 1.20.0.2 on OSX 10.9.3 with both -staticlib and -threaded enabled.
The library I'm building exports several functions using FFI to be called from ObjectiveC in an Xcode project. This works fine with just -staticlib enabled, but now I realize I need to call into my Haskell library from multiple OS-threads simultaneously. But when I add -threaded to ghc-options I get an error when linking:
error: libtool: can't locate file for: -lpthread
error: libtool: file: -lpthread is not an object file (not allowed in a library)
Complete ouput:
$ cabal build
Resolving dependencies...
Configuring dpsync-0.1.0.0...
Building dpsync-0.1.0.0...
Preprocessing library dpsync-0.1.0.0...
[ 1 of 11] Compiling Link ( src/Link.hs, dist/build/Link.o )
...
[11 of 11] Compiling HsCocoa ( src/HsCocoa.hs, dist/build/HsCocoa.o )
Linking liba.a ...
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lpthread
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lpthread is not an object file (not allowed in a library)
The linker command that fails looks like this (... replaces a bunch of -l and -L options):
libtool -static -o liba.a dist/build/HsCocoa.o ... -lCffi -lpthread
Does anyone know what could be wrong?
Entire project on GitHub
Edit:
After discussing this on Haskell Cafe it was suggested that this could be a bug in GHC. I created a ticket here: https://ghc.haskell.org/trac/ghc/ticket/9189

Missing symbol in Haskell libclang binding: clang_toggleCrashRecovery

have a bug with libClang, then i install it with cabal at the end i get:
[13 of 13] Compiling Clang ( src/Clang.hs, dist/build/Clang.o )
In file included from ./src/Clang/FFI_stub_ffi.h:6,
from src/Clang/FFI_stub_ffi.c:4:0:
/usr/local/lib/ghc-7.0.3/include/HsFFI.h:29:0:
warning: "__STDC_LIMIT_MACROS" redefined
<command-line>:0:0:
note: this is the location of the previous definition
src/Clang/FFI_stub_ffi.c: In function ‘prim_getCString’:
src/Clang/FFI_stub_ffi.c:33:0:
warning: assignment discards qualifiers from pointer target type
src/Clang/FFI_stub_ffi.c: In function ‘prim_toggleCrashRecovery’:
src/Clang/FFI_stub_ffi.c:2181:0:
warning: implicit declaration of function ‘clang_toggleCrashRecovery’
Registering LibClang-0.0.9...
when i now want to compile a script with ghc that uses Clang i get:
ghc --make test.hs -L.
[1 of 1] Compiling Main ( test.hs, test.o )
Linking test ...
/home/foo/.cabal/lib/LibClang-0.0.9/ghc-7.0.3/libHSLibClang-0.0.9.a(FFI_stub_ffi.o): In function `prim_toggleCrashRecovery':
FFI_stub_ffi.c:(.text+0x1577): undefined reference to `clang_toggleCrashRecovery'
collect2: ld returned 1 exit status
someone a idea what to do?
I can reproduce this on Arch Linux / x86_64: my libclang build emits a warning about the missing symbol,
src/Clang/FFI_stub_ffi.c:2181:1:
warning: implicit declaration of function ‘clang_toggleCrashRecovery’
[-Wimplicit-function-declaration]
Registering LibClang-0.0.9...
Installing library in /home/dons/.cabal/lib/LibClang-0.0.9/ghc-7.0.3
Registering LibClang-0.0.9...
and linking a test program:
import Clang
main = print "yes"
fails with:
$ ghc --make A.hs
Linking A ...
/home/dons/.cabal/lib/LibClang-0.0.9/ghc-7.0.3/libHSLibClang-0.0.9.a(FFI_stub_ffi.o):
In function `prim_toggleCrashRecovery':
FFI_stub_ffi.c:(.text+0x3513): undefined reference to `clang_toggleCrashRecovery'
collect2: ld returned 1 exit status
The process of solving these kind of linker errors is to identify which C library archive that symbol lives in. Searching in my libclang install, I can't find this symbol:
$ find . -type f -exec grep toggleCrashRecovery {} \;
$ grep toggleCrashRecovery /usr/lib/llvm/*
$ grep toggleCrashRecovery /usr/lib/llvm/*/*
zsh: no matches found: /usr/lib/llvm/*/*
which is a clue that it might be something only available in a different version of libclang. I'm using clang/llvm 2.9, which does not have this symbol, while google does turn up some older headers that do include it. So my best guess is that this symbol is no longer available in LLVM, and thus the current haskell/libclang package depends on LLVM/Clang 2.8.
Solution:
Download the libclang source,
$ cabal unpack libclang
and patch it to remove references to the toggle* functions.
$ ghc --make A.hs
[1 of 1] Compiling Main ( A.hs, A.o )
Linking A ...
A patched version is here: http://www.galois.com/~dons/tmp/LibClang-0.0.10.tar.gz
I've also forwarded this info to the author.
Thanks Don for the quick fix.
This issue is fixed with the latest version on Hackage:
http://hackage.haskell.org/package/LibClang-0.1.0
Please "cabal update" and you should be good to go.
Alternatively, you could get the source from https://github.com/chetant/LibClang

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