GHC 7.8.3 not producing binary - haskell

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

Related

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.

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

Haskell dynamic library

http://www.vex.net/~trebla/haskell/so.xhtml describes how to compile shared library.
About compiling command:
ghc -O2 -dynamic -shared -fPIC -o libEval.so Eval.hs hsbracket.c -lHSrts-ghc7.6.3
it says:
(Could you omit -dynamic to request static libraries of other packages? Not really, they were not generated with -fPIC. In particular it is illegal on x86_64.)
Why is it so? What should one do to compile shared library without libHS* dependencies?
Since Kaiko contacted me privately for an answer, might as well post it here...
Short version
By omitting -dynamic you would be trying to take all the static .a libs and link them into one massive .so file. Those .a libs were themselves built without -fPIC. All code that ends up on a .so file must be built with -fPIC (at least on ELF x86-64). Thus the linking would fail in this case because -fPIC is required but the libs were not built with -fPIC.
Long version
There are a few things that vary between different ways of building
static and dynamic libraries:
Is it built as a .a archive or as a .so (or .dll/.dynlib) object?
Is it built with -fPIC, position independent code or not?
Are external symbols expected to be in the same DSO or an external DSO?
In principle, lots of different combinations of these things make sense
but in practice only a few are used.
On Linux (ELF), there are two standard approaches to building libraries,
fully static and fully dynamic. In the fully static approach the answer
to question 1,2,3 above are: .a archive, no -fPIC, same DSO. In the
fully dynamic approach the answers are: .so lib, -fPIC, external DSO.
Now what you want to do is different. You want all libraries to be built
as .a files, but with -fPIC and external symbols expected to be in the
same DSO. This would then let you link all those libraries together into
one huge shared library. So the crucial difference is the use of -fPIC,
since on ELF (specifically x86_64) code that ends up in a shared lib
must be built with -fPIC.
By contrast, on Windows, GHC can do exactly what you want, to link all
the Haskell libs (including the RTS etc) into one massive shared lib
(.dll). This is because on Windows (unlike ELF), position independent
code does not matter. So on Windows, one is able to take the static
libraries and link them into a big shared library.
In principle this should also be possible on Linux, if all of the
Haskell libraries were built statically but with -fPIC. This is not the
default, and that is the immediate reason why you cannot omit -dynamic
in this case on Linux.
So in principle, one could try rebuilding ghc and the core libraries
from source using the -fPIC flag and then see if it then works to omit
-dynamic and link everything into one huge shared lib.
Yes, compiling with -fPIC helps. Here is how to do that.
ghc-7.8.4/mk/build.mk:
SRC_HC_OPTS = -H64m -O
EXTRA_HC_OPTS = -fPIC
SRC_CC_OPTS = -fPIC -O
GhcStage1HcOpts = -fasm -O0
GhcStage2HcOpts = -fasm -O0
GhcLibHcOpts = -fasm -O2
GhcLibWays = v dyn
DYNAMIC_GHC_PROGRAMS = YES
DYNAMIC_BY_DEFAULT = NO
SplitObjs = NO
HADDOCK_DOCS = NO
BUILD_DOCBOOK_HTML = NO
BUILD_DOCBOOK_PS = NO
BUILD_DOCBOOK_PDF = NO
While you compile ghc:
export EXTRA_CONFIGURE_OPTS="--disable-library-profiling --enable-shared"
To build cabal packages with -fPIC use:
cabal install --enable-shared --ghc-option=-fPIC text
Test file foo.hs (Data.Text is used to see if cabal packages also work):
import Foreign.C as C
import Data.Text as T
import Data.Text.Foreign as T
foreign export ccall len :: CString -> IO CInt
len t = C.peekCString t >>= return . CInt . fromIntegral . T.length . T.pack
main = return ()
Dynamic build:
ghc -dynamic --make foo.hs
Dynamic mixed with static build (not sure if pthread is needed but it illustrates how to add dynamic linking):
ghc -fPIC -shared --make -o libfoo.so \
-optl-Wl,-Bstatic -lHSrts -lCffi \
-lHSbase-4.7.0.2 -lHSinteger-gmp-0.5.1.0 -lHSghc-prim-0.3.1.0 \
-optl-Wl,-Bdynamic -lpthread foo.hs

"requested module differs from name found in the interface file"

What I want is: cabal to build my modules; make to build this one script.
The script links to Objective-C (see https://github.com/mchakravarty/language-c-inline/tree/master/tests/objc/marshal-array). when I build the script, it fails on the import:
$ make
Main.hs:1:1:
Bad interface file: dist/build/Commands/OSX/Events.hi
Something is amiss; requested module main:Commands.OSX.Events differs from name found in the interface file commands-0.0.0:Commands.OSX.Events
here are some file contents:
$ cat Makefile
PACKAGES = -package template-haskell -package language-c-quote -package language-c-inline -package commands
FRAMEWORKS = -framework Carbon -framework Cocoa -framework Foundation
LDFLAGS = $(PACKAGES) $(FRAMEWORKS)
Main: Main.o
cabal exec -- ghc -o Main Main.o $(LDFLAGS)
Main.o:
cabal build
cabal exec -- ghc -c Main.hs -idist/build/ -v
...
$ cat commands.cabal
exposed-modules: Commands.OSX.Events
hs-source-dirs: sources
...
$ ghc --show-iface dist/build/Commands/OSX/Events.hi
interface commands-0.0.0:Commands.OSX.Events 7083
...
$ cat sources/Commands/OSX/Events.hs
module Commands.OSX.Events where
...
$ cat Main.hs
import Commands.OSX.Events
...
the cabal build is successful, and executable compiles and runs successfully, if I just put everything in the same directory, and ignore cabal.
can I tell GHC that some module is part of some package?
can I make a cabal executable, with these external dependencies?
any other solutions?
explicitly naming the modules package worked:
ghc -package-name commands-0.0.0
http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/packages.html

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