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

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

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.

own symbol not found cabal test

I'm try to add some test to a little project in Haskell. (I'm using a cabal sandbox on Mac OS)
Everything is fine (the Haskell code compile and run perfectly in cabal repl.
But when I try to build the test, it compiles fine, but crashes at link time, claiming that it can't find some symbols
which are from my package.
It seems that it's not trying to link with my own module library, even though I added the dependency in the cabal test suite configuration. If I didn't it could compile, did It ?
So is it a (cabal ) configuration problem or something more major ?
I assume you Cabal file has a library, executable, test-suite layout. Then you must list the relevant modules in the library section of your Cabal file under exposed-modules or other-modules. In any case, all the modules of your package must be listed in the Cabal file.

Cabal install needs C library: Windows

I am trying to cabal install yesod on my Windows machine. I have a relatively fresh install of the Haskell Platform. The cabal install failed, reporting that I need the sqlite3 C library in order to install "persistent", a package which Yesod relies upon.
cabal: Missing dependency on a foreign library:
* Missing C library: sqlite3
So I went to http://www.sqlite.org/download.html and grabbed both the C source and the precompiled binary. I tried using both, to no avail:
cabal install persistent --extra-lib-dirs=C:\Path\To\C\Source\Files
cabal install persistent --extra-lib-dirs=C:\Path\To\Binary
In both cases, I got the same result: it didn't work. :( What can I do to give cabal the C library it needs? (sqlite3 in this case)
So, facepalm. I didn't need the source, I didn't need the exe. I needed the dll.
Under the "precompiled binaries for Windows" section of the website mentioned in my question, I downloaded and extracted the zip file with sqlite3.def and sqlite.dll. Then I used
cabal install persistent --extra-lib-dirs=C:\Path\To\DllAndDef
The installation appears to have completed successfully. Afterwards, I did a cabal install yesod, which also appears to have completed successfully.
I suppose if I had put the dll somewhere magical, then I wouldn't have had to use the --extra-lib-dirs= option.

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.

ghc can't find my cabal installed packages

I've installed ghc 6.12.3, and then the Haskell Platform. I'm trying to compile a test program:
$ ghc test.hs
test.hs:3:0:
Failed to load interface for `Bindings':
Use -v to see a list of the files searched for.
so, naturally, I do
cabal install Bindings
Which works fine, and places the package in ~/.cabal/lib/bindings-0.1.2 The problem is, that when I go to compile again with ghc, it still doesn't find the package I've installed with cabal.
compiling in verbose mode gives:
ghc -v test.hs
Using binary package database: /home/ludflu/ghc/lib/ghc-6.12.3/package.conf.d/package.cache
Using binary package database: /home/ludflu/.ghc/x86_64-linux 6.12.3/package.conf.d/package.cache
As suggested by another stackoverflow user, I tried:
ghc-pkg describe rts > rts.pkg
vi rts.pkg # add the /home/ludflu/.cabal/lib to `library-dirs` field
ghc-pkg update rts.pkg
But to no avail. How to I add the .cabal to the list of package directories to search?
Thank you!
You can check which packages are installed with ghc-pkg list. It may be that you need to either specify the packages to ghc with -package <pkgname> or I believe adding --make to will trigger a chasing down of dependencies, including packages.
Edit: the bindings package is obsolete indeed, see the hackage page. This isn't a package management problem, the only module available is Bindings.Deprecated, which you are perfectly able to load, even though it is an empty module. I believe the relevant parts have been broken out into bindings-<module>, so if you want the bindings functionality you should look to those packages.
http://www.haskell.org/haskellwiki/Cabal-install
One thing to be especially aware of, is that the packages are installed locally by default by cabal, whereas the commands
runhaskell Setup configure
runhaskell Setup build
runhaskell Setup install
install globally by default. If you install a package globally, the local packages are ignored. The default for cabal-install can be modified by editing the configuration file.
I was getting the same error with the runhaskell command. I used the cabal in the directory that had the .cabal file and was able to resolve the error.

Resources