Cabal library vs cabal-install. what's the difference? - haskell

When I do cabal --version I see:
cabal-install version 0.14.0
using version 1.14.0 of the Cabal library
so what's the difference? i thought that when i do cabal build i use only one program. why is it split into two separate programs with different versions?

The Cabal library defines how package descriptions are parsed and structured, and describe part of the process of building and installing a package. The cabal-install package defines the cabal application. It uses the library to effectively understand what a package description is.
This is a common structure for software: implement all your pure and reusable business logic in a library (the Cabal library does most, but not all, of the work purely related to package descriptions), and implement all your user interface stuff and other 'details' in an application that uses the library (the cabal-install package defines the CLI tool, and implements the details of fetching packages from Hackage).

Related

Cabal install tidal ends with warning

I'm trying install tidal in command line this way:
cabal install tidal
but it ends with this message:
Warning: You asked to install executables, but there are no executables in
target: tidal. Perhaps you want to use --lib to install libraries instead.
Return of:
cabal install tidal --lib
is:
Resolving dependencies...
Up to date
If I check ghk-pkg list, there is no package tidal
...
Have somebody similar problem or what I'm doing wrong?
My environment is:
Windows 10 Education
Haskell 8.4.3
Cabal 3.2.0.0
Ghc 8.10.1
Thank you for help.
Like Stack for a longer time, Cabal-install does now (as of 3.2) not really install libraries anymore – in the sense of, change the computer's state so that GHC can access the library on it†. Both tools only install executables now. It used to do that for libraries too, but that was stopped with the now default Nix-style builds.
Now (and, really, also already before), the way to use a library is instead to just depend on it, and let Cabal figure out behind the scenes if it needs to be installed. I.e., you add a .cabal file to your .hs source file with build-depends: tidal in it. Then when you say cabal install ., it will first download and install the library before then using it for building your own executable.
†Of course both Stack and Cabal do technically speaking install libraries, just they don't globally register them. I.e., cabal knows where it has installed the library, but you're not really supposed to know about that. It's in the spirit of continuous integration: if your code builds now with the particular state of libraries you happen to have installed, that's not very reliable. If it builds with just those libraries that are explicitly listed in a project file, the chances are much better that future-you (or somebody else) will still be able to use your code on another computer without hours of figuring out what libraries to install first.
cabal install --lib tidal doesn't install the library binaries in a location managed by ghc-pkg. The binaries remain in the Cabal "store".
What it does is to create a plaintext GHC package environment file that is picked up by standalone invocations of ghc and ghci and tells them where to look for the extra libraries.
By default (as mentioned in the docs) this package environment file will be created at ~/.ghc/$ARCH-$OS-$GHCVER/environments/default and will be picked by ghc and ghci invocations made anywhere.
We can also supply an extra --package-env parameter to create the environment file in a local folder, which will only affect ghc and ghci invocations made in that folder. For example:
cabal install --lib --package-env . tidal
cabal projects themselves ignore environment files, as their package environments are constructed from the build-depends section of the cabal file for the sake of reproducibility. But environment files are useful for not having to create a cabal project in the first place, if you only need it for playing with the library in ghci, or if you are compiling simple programs using ghc only.

Compiling haskell source as dynamic library

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.

Re-using Haskell Platform prebuilt libraries within a cabal sandbox?

When I build a Cabal project without a sandbox, Cabal uses existing libraries from my Haskell Platform installation. However, if I try to do the same inside a Cabal sandbox, Cabal forcibly rebuilds all my dependencies into the sandbox.
To save on build times and disk space, it'd be great to be able to instruct Cabal to use existing Haskell Platform libraries instead of rebuilding them. Is this possible?
Example (files in a gist):
executable blog
hs-source-dirs: .
main-is: Test.hs
build-depends: base >= 4.5 && < 5
, text
If I cabal build in the directory containing this .cabal file, my Test module gets built against the Haskell Platform version of text.
However, if I do the same in a sandbox:
cabal clean # (or alternatively clone an empty gist)
cabal sandbox init
cabal build
I get this:
$ cabal build
Package has never been configured. Configuring with default flags. If this
fails, please run configure manually.
Resolving dependencies...
Configuring install-test-0.1...
cabal: At least the following dependencies are missing:
text -any
If I now go and cabal install, the latest text library is built from scratch under my sandbox.
As per cabal-install bug #1695, this is currently not supported. It's something that may eventually be built, see multi-instance packages for more information.
If anyone's reading and cares, an alternative that should work for some users would be to share a single cabal sandbox among multiple projects. This way you could still keep your Haskell Platform installation separate from library installations you need during your development. More on that in An Introduction to Cabal sandboxes

How to get cabal-install Distribution.Client.IndexUtils

I were trying to add cabal-install and Cabal-install to .cabal file but.
At least the following dependencies are missing: Cabal-install -any
Why there is no cabal-install?
So how can I get Distribution.Client.IndexUtils except of embedding cabal-install sources?
and Distribution.Client.IndexUtils too.
Or maybe I can replace it with something?
Unfortunately, cabal-install is a package that provides an executable, but no library. Therefore, there is no easy way to use functionality provided by cabal-install in other tools. A common approach is to write wrapper programs that invoke the cabal binary and query it for information.
Having some of the functionality of cabal-install available as a library is a valid and reasonable goal, but it might take a while before this happens.
As to the error message: If a package installs only an executable, it is not registered as a library with GHC. Therefore, if you list cabal-install as a dependency of another package, you will get the error message that cabal-install is missing (as a library).

How are `ghc-pkg` and `cabal` programs related? (Haskell)

As I know cabal is a program to manage installation of packages like FreeBSD's pkg_add.
But there is another tool called ghc-pkg. I don't know why there are two different programs. What's the role of each of them and how are they related?
Cabal is a building and packaging library for Haskell, kind of "Haskell autotools". It reads .cabal files and Haskell packages usually have a file Setup.hs which uses Cabal to build the package. Then there's also cabal command provided by the cabal-install package. It provides commands for running Setup.hs script and some package management functions, like installing packages directly from Hackage. You should read this blogpost by Ivan Miljenovic which explains the role of Cabal, cabal-install and Hackage quite well.
ghc-pkg is a lower-level tool for poking GHC's package database. Cabal is intended to work with every Haskell compiler, whereas ghc-pkg is obviously specific to GHC. You can't use ghc-pkg to build anything, you can just register packages you've built otherwise.
cabal is just an interface layer to ghc-pkg with some added features. It's only important to know ghc-pkg because uninstall functionality was not added to cabal, but can be done directly with ghc-pkg.

Resources