[Haskell-cafe] Haskell plugin dynamic linking issue
Albert Y. C. Lai
trebla at vex.net
Mon Apr 10 22:46:45 UTC 2017
On 2017-04-10 04:58 PM, Lana Black wrote:
> ~/devel/hs/cabal-bug> cabal build
> Package has never been configured. Configuring with default flags. If this
> fails, please run configure manually.
> Resolving dependencies...
> Configuring cabal-bug-0.1...
I am surprised that at this point you did not receive the warning I
Warning: Instead of 'ghc-options: -lHSrts-ghc8.0.2' use
In my http://www.vex.net/~trebla/haskell/so.xhtml I use the
extra-libraries route (and build-type: Configure to automate "8.0.2").
Also I do not use ghc-options, see below.
> Building cabal-bug-0.1...
> Preprocessing library cabal-bug-0.1...
> [1 of 1] Compiling Cabal.Bug ( src/Cabal/Bug.hs,
> dist/build/Cabal/Bug.o )
> Linking a.out ...
This a.out is not an executable. It is a shared library. The name
"a.out" is a historical generic bland default name for any linker output
whenever the user fails to specify "-o realname". Linker output could be
executable or library depending on other flags.
Now to see why this a.out exists at all, you really should use "cabal
build -v" to see how cabal uses GHC. But the short story is:
cabal calls GHC at least 3 times:
1st time is to compile *.hs files to *.o files, e.g., Bug.hs to Bug.o.
(If you have multiple *.hs files, it is still one call, and you also see
a -j2 or -j4 or -j65536 according to your number of CPU cores to tell
GHC to parallelize.)
2nd time is to produce the *.a library.
3rd time is to produce the *.so library.
Now, if you hardcode the blunt sledgehammer that is ghc-options: -fPIC
-dynamic -shared, as opposed to letting cabal do it at the right times
(namely, -shared during the 3rd time only), then the extraneous -shared
during the 1st time, which is supposed to be *.o only, tricks GHC into
calling the linker to produce an extraneous *.so (except there is no -o
so the name comes out as a.out).
But do not think that you can declare victory now and take this a.out
and get away with it.
For all practical purposes you will need to include some C code in the
library. See again my article for why. But the short story is: Who's
gonna call hs_init?
The 1st call to GHC does not mention the C code whatsoever. The a.out
thus produced will be missing the C code. It is incomplete.
There are extra calls after the 1st and before the 2nd to compile *.c to
Only by the 3rd call are all *.o files, from both Haskell and C, brought
together into a complete *.so. (Well, the 2nd call too, but you are not
going after the *.a.)
More information about the Haskell-Cafe