Compiling haskell source as dynamic library - haskell

I'm trying to compile a Haskell source package as a dynamic library to be used with OCaml code. I tried using the --enable-shared option with cabal install on the .cabal file of the source, I got a Perhaps you haven't installed the "dyn" libraries for package 'zeromq4-haskell-0.6.5' error. After a little googling, I realised that the dependencies must also be compiled as dynamic libraries. I downloaded the source package for zeromq and tried installing the zeromq package with the --enable-shared option. This time I got a similar error with one of zeromq's dependencies. I tried doing this 4-5 times and get an error with a different dependency at each level.
Am I making a mistake here? How can I get all of the dependencies to install as dynamic libraries?
Thanks!

If you generally want to have shared libraries, you can permanently enable it in your .cabal/config:
shared: True
However, it will only affect libraries installed after that, so you may want to purge all libraries and start over again.
If this is just a one-shot, you may create a cabal sandbox just for that purpose:
cd yourlib
cabal sandbox init
cabal install --enable-shared
The result will be in the directory .cabal-sandbox.

Related

How to make GHC generate dynamically linked binaries by default?

Is it possible to change cabal or GHC settings so that cabal install generates dynamic binaries and libraries by default?
I'm using GHC 8.2.2, installed using apt-get in Ubuntu (16.04) without Haskell Platform or stack. Searching around, I found the SO question Why can't cabal build mighttpd2 dynamically? . The answers/comments there said something about adding --enable-shared --enable-executable-dynamic when cabal install. And this can be done manually for all dependency libraries (which would be a pain).
In Small Haskell program compiled with GHC into huge binary, the accepted answer says that one needs to:
cabal install some_package --enable-shared --reinstall
The option -dynamic is also mentioned.
My question is:
Is it possible to change the options in the cabal configuration file (~/.cabal/config) from the very beginning so that all binaries and their dependency libraries use dynamic linkage (i.e. with --enable-shared --enable-executable-dynamic or -dynamic by default)?
Indeed, you can alter your ~/.cabal/config file to have the following lines:
shared: True
executable-dynamic: True

Cabal can't find foreign libraries

Recently I was trying to install llvm-general-3.5.1.0 package.. for about a week. Basically I am getting this error: link. My situation is identical. Windows 10, ghc 7.10.2, cabal 1.22.4.0. I installed llvm 3.5.2 from sources with cmake and everything went fine. In llvm/lib directory I have *.lib files (eg. LLVMAnalysis.lib).
But somehow cabal can't see those libraries and gives this frustrating error:
Configuring llvm-general-3.5.1.0...
setup.exe: Missing dependencies on foreign libraries:
* Missing C libraries: LLVMLTO, LLVMObjCARCOpts, LLVMLinker, LLVMipo,
LLVMVectorize, LLVMBitWriter, LLVMCppBackendCodeGen, LLVMCppBackendInfo,
LLVMTableGen, LLVMDebugInfo, LLVMOption, LLVMX86Disassembler,
LLVMX86AsmParser, LLVMX86CodeGen, LLVMSelectionDAG, LLVMAsmPrinter,
LLVMX86Desc, LLVMX86Info, LLVMX86AsmPrinter, LLVMX86Utils, LLVMJIT,
LLVMIRReader, LLVMAsmParser, LLVMLineEditor, LLVMMCAnalysis,
LLVMMCDisassembler, LLVMInstrumentation, LLVMInterpreter, LLVMCodeGen,
LLVMScalarOpts, LLVMInstCombine, LLVMTransformUtils, LLVMipa, LLVMAnalysis,
LLVMProfileData, LLVMMCJIT, LLVMTarget, LLVMRuntimeDyld, LLVMObject,
LLVMMCParser, LLVMBitReader, LLVMExecutionEngine, LLVMMC, LLVMCore,
LLVMSupport
This problem can usually be solved by installing the system packages that
provide these libraries (you may need the "-dev" versions). If the libraries
are already installed but in a non-standard location then you can use the
flags --extra-include-dirs= and --extra-lib-dirs= to specify where they are.
I really want to use this package on my Windows, but nothing seems to work (I tried everything like --extra-lib-dirs and compiled also with MinGW and VS - the same problem).
I can't accept the fact that it won't install. I mean, there must be some way to fix Setup.hs from this cabal package or something. Does anyone have an idea what can be wrong with cabal in this case and how can I try to workaround this? I don't know how exactly cabal works, maybe someone with this knowledge will have an idea? Or maybe there is a way to do this without cabal?
Ok, i've managed to build it and, i think, found the root of the issue.
First, steps to build:
Get the MinGW. My installation of MinGW has gcc 4.8.
Get 32-bit MinGHC.
Compile LLVM 3.5 with MinGW's gcc and install it somewhere.
Copy contents of MinGW installation directory into MinGHC Install
Dir\ghc-7.10.2\mingw, replacing conflict files.
In the command line set your PATH so it has haskell toolset from
MinGHC (i recommend using switch .bat scripts) and llvm-config.exe.
Get the llvm-general package source either using cabal fetch or
downloading via browser from hackage.
Replace cc-options: -std=c++11 line of llvm-general.cabal with
cc-options: -std=gnu++11.
Finally, cabal configure and cabal build should work.
I have been changing my build environment many times, so if this doesn't work for you let me know, i probably forgot something.
Now let's go into details.
What we thought is a bug of cabal is not, actually. The problem is that both stack and MinGHC (and Haskell Platform, i guess) use quite old gcc - 4.6. This gcc has even two defects:
It doesn't support -std=c++11 and LLVM 3.5 can't be built using it.
As a consequence, this gcc can't be used by ghc when compiling
llvm-general, because it can't parse LLVM headers properly.
Even if it could, its linker can't link against LLVM libs compiled by
MinGW using gcc 4.8. This is why cabal was telling you it
couldn't find LLVM libs. I've hacked Setup.hs so that it wouldn't
look for these libs, but pass -lLLVMSomething to linker via -pgml
ghc option. This lead to clear error message:
ld.exe: ignoring libLLVMSupport.a ...
ld.exe: can't find -lLLVMSupport
So, the cabal was actually finding these libs, but was dropping them because they couldn't be linked to.
Ideally, the solution would be to update mingw distribution used by stack/MinGHC. But as a workaround you can just replace old gcc with new one.
Finally, -std=gnu++11 is used because current MinGW release is affected by this bug, which prevents compilation of c++ bits of the package. Whew, that was a long way.

cabal install --disable-prof not working?

To save time, I am trying to build a package (in a sandbox) with --disable-doc --disable-prof, but it's failing: when compiling some dependency (crypto-api), I get
Could not find module ‘System.Entropy’
Perhaps you haven't installed the profiling libraries for package
‘entropy-0.3.7#entro_GdlGosmsZhO5QKbUBFjD3f’?
Sure I have not, and I don't want to.
What's happening? (The workaround is to --disable-doc only.)
Odds are a package lower in the dependency tree is forcing profiling builds, and then failing when the package it depends on has not been built that way.
You used the wrong flags.
You need --disable-profiling --disable-documentation

Unable to install yesod-bin

I'm updating my yesod framework to the latest yesod 1.2 version. I've installed yesod-platform (painfully....had to manually delete old dependency....cabal hell), now I need to install yesod-bin and it should be done. However, after sudo cabal install yesod-bin I'm getting the following error.
Building yesod-bin-1.2.0...
Preprocessing executable 'yesod-ld-wrapper' for yesod-bin-1.2.0...
[1 of 1] Compiling Main ( ghcwrapper.hs, dist/build/yesod-ld-wrapper/yesod-ld-wrapper-tmp/Main.o )
Linking dist/build/yesod-ld-wrapper/yesod-ld-wrapper ...
/usr/bin/ld: cannot find -lHStar-0.4.0.1
/usr/bin/ld: cannot find -lHSoptparse-applicative-0.5.2.1
/usr/bin/ld: cannot find -lHSghc-paths-0.1.0.9
/usr/bin/ld: cannot find -lHSfsnotify-0.0.6
/usr/bin/ld: cannot find -lHShinotify-0.3.5
collect2: ld returned 1 exit status
Failed to install yesod-bin-1.2.0
cabal: Error: some packages failed to install:
yesod-bin-1.2.0 failed during the building phase. The exception was:
ExitFailure 1
According to this, I feel it may have something to do with privileges I'm not sure.
EDIT: So I only found the following two libraries.
/usr/lib/haskell-packages/ghc/lib/tar-0.3.2.0/ghc-7.4.1/libHStar-0.3.2.0.a
/usr/lib/haskell-packages/ghc/lib/ghc-paths-0.1.0.8/ghc-7.4.1/libHSghc-paths-0.1.0.8.a
I'm trying to update libghc-tar-dev to the newest version 0.4.0.1. However, 0.3.2.0 is the newest version on apt-get what are my options?
First, I'd check to see if you have the libraries libHStar, libHSoptparse-applicative, libHSghc-paths, libHSfsnotify and libHShinotify. If you installed the haskell platform using your distro's package manager, I suspect you'll find those libraries in /usr/local/lib/ghc-*.*.*/. For example, you might search for the first library using this command:
sudo find /usr/local/lib -name 'libHStar*'
If you don't have those libraries, then I think you can get them by using your distro's package manager to install the following:
libghc-tar-dev
libghc-optparse-applicative-dev
libghc-ghc-paths-dev
libghc-fsnotify-dev
libghc-hinotify-dev
If you already have those libraries, then you could adapt the fix suggested in your link:
sudo chmod a+r /usr/local/lib/ghc-*/libHS*
UPDATE:
The standard recommendation seems to be that you should always use your linux distro's package manager to install stuff, rather than using the cabal command directly. And if a package you want isn't available yet on your distro, request it. This approach is the safest, because all of the dependencies have been sorted out for you. The disadvantage is that you won't usually have the latest release. I see that there is a yesod package on Ubuntu. I have no idea if it contains yesod-bin (I'm not familiar with yesod), but if it does, that's the safest approach. The downside is that you will probably have to wipe out your cabal library and start from scratch (re-install haskell-platform, then yesod).
Another option, which seems to be the road you're on, is to use your package manager to install the haskell-platform, but after that use the cabal command to install any haskell-y stuff. You'll still use your package manager to install things that can't be installed using cabal (e.g., non-haskell stuff). If you do this, you can avoid a lot of cabal hell by never running cabal as root, and never letting your package manager do anything that can be done using cabal. The main disadvantage of this approach is that you have to deal with library dependencies yourself, as you've discovered. If you want to continue down this road, you might be able to get everything you need by switching to some development/test build for Ubuntu. Or you may have to get the correct versions of the libraries you need and manually install them.

Could not find module Prelude... dyn libraries for package base?

Trying to follow the solution proposed in the answer to reducing haskell's binary question, I keep getting the error, when I install with --enable-shared option:
> cabal install opengl --enable-shared --reinstall
...
Could not find module `Prelude'
Perhaps you haven't installed the "dyn" libraries for package `base'?
Tried everything. I'm using apt-get installedhaskell-platform (with ghc 7.4.1), on Ubuntu 12.04, 64bit.
ANY tips?
It seems that Ubuntu's Haskell platform doesn't include dynamic libraries.
You can try installing ghc-dynamic, that should work, I assume the distro packagers know what they're doing. You would probably need to install the *-dynamic packages for several libraries included in the platform too.
In case it doesn't work, the only suggestions I can make is to compile GHC yourself from source (using the installed GHC), or use a vanilla GHC bindist, those come with dynamic libraries, as far as I'm aware.
Both would require reinstalling (recompiling included) the libraries, though (perhaps best to compile the vanilla platform from source then), so I recommend trying the distribution packages first.

Resources