Haskell Cabal: omitting version a big mistake - haskell

I ran cabal build on a *.cabal file that doesn't have a version: specified and it seems to have confused cabal. When I put back the version specification, I got
$ cabal build
Resolving dependencies...
TODO: add support for multiple packages in a directory. Got
yah-0.1.0.0
yah-0.1.0.0
CallStack (from HasCallStack):
error, called at src\\Distribution\\Client\\ProjectOrchestration.hs:586:9 in cabal-install-3.8.1.0-inplace:Distribution.
Client.ProjectOrchestration
That is, normally the yah.cabal file would read
cabal-version: 3.0
name: yah
version: 0.1.0.0
license: etc., etc.
and cabal build was fed the above without the version and maybe without the cabal-version -- not sure. In any case, starting over with cabal init doesn't fix it, but other projects can be compiled fine.
My guess is that the various modules that are in the yah project are registered somewhere/somehow and it's not clear how to expunge that and start over. I'm on Windows, cabal 3.8.1.0. I've looked in C:\cabal, C:\ghccup, C:\Users\...\AppData\Roaming\cabal...

It looks like you have more than one .cabal file in that directory. Remove the one that's not named yah.cabal.

Related

Cabal cannot find locally sourced (yet correctly installed) packages

I recently upgraded to Cabal 3.2 (and GHC 8.10) and I am running into some major issues that make some of my project non-buildable anymore...
Thorough description of the problem
Here is a minimal (not) working configuration that fails every time:
I start off with a clean Cabal configuration (by deleting ~/.cabal); the reason for that will appear later in the post. I run cabal update to recreate the .cabal directory and to ensure Cabal is working.
I create a project (let's call it test1) using cabal init. This is a library project with one exposed module (conveniently named Test1) that exports some dummy function foo. I run cabal build, then cabal install --lib; everything is running smooth, so far so good.
Just to be sure, I leave the project directory and fire up GHCi. I type in :m Test1 to load the module I created earlier, and it works! I can type in foo ... and see my function executed. Also, I list the content of ~/.cabal/store/ghc-8.10.xxx and see that the test1-xxx directory is there.
I then create a new project, test2, still using cabal init. This time, I configure it to be an executable, and I add test1 as a dependency (using the build-depends field). But this time when I run cabal build, I run into some issue:
~/projects/haskell/test2> cabal build
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: test2-0.1.0.0 (user goal)
[__1] unknown package: test1 (dependency of test2)
[__1] fail (backjumping, conflict set: test1, test2)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: test2, test1
It seems to me like package test1 cannot be found, however I can access it from GHCi (and GHC for that matters) and it is present in ~/.cabal/store...
But unfortunately there is more.
I create a third project, test3. This is a library, and it depends on nothing else than base (so in particular it does not depend on test1). The lib exposes one module, Test3, with one function exported, bar. I run cabal build, no problem here. But when I want to install test3 with cabal install --lib I run into some errors:
~/projects/haskell/test3> cabal install --lib
Wrote tarball sdist to
/home/<user>/projects/haskell/test3/dist-newstyle/sdist/test3-0.1.0.0.tar.gz
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] unknown package: test1 (user goal)
[__0] fail (backjumping, conflict set: test1)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: test1
It seems that it cannot find test1, although it has been installed correctly; may be this is a remnant of the failed build of test2 though...
Just to be sure, I fire up GHCi and type in :m Test3, but GHCi tells me that it cannot find module Test3 (and even suggests this is a typo and I was meaning Test1), showing that test3 indeed did not get installed, although it got successfully built...
Okay there is one more quirk to this whole situation: I create once again a new project with cabal init, called test4, which is an executable that (again) depends on nothing else than base. I keep the default Main.hs (that just prints "Hello, Haskell!"). I run cabal build: no problem. Then I run cabal install and... No problem either? I run test4 in a random location and it fires up the executable, printing "Hello, Haskell!" in the terminal...
And there is one last thing: I go to some random location and I run cabal install xxx --lib where xxx is a library package available on Hackage (for example xml) and:
~> cabal install xml --lib
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] unknown package: test1 (user goal)
[__0] fail (backjumping, conflict set: test1)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: test1
This is the reason why I need to nuke .cabal regularly... Right now I seem to be in some kind of stale state where I cannot install any library anymore.
Technical configuration and notes
I am running Cabal 3.2.0.0 and GHC 8.10.0.20200123. I installed them from the hvr/ghc PPA, and I made sure there are no other versions of those tools anywhere on my computer.
Just as a note, I am running Ubuntu 18.04.4 LTS (with XFCE so XUbuntu to be exact). Everything else (seem to be like it) is up to date.
Last thing, regarding the *.cabal files I use for building, they are pretty much the ones generated by cabal init, except I switch executable xxx for library in the case of libraries, and I simply add a exposed-modules field for exposing modules for the libraries (so Test1 for test1 and Test3 for test3 respectively). I also use build-depends in test2 to make the project depend on test1. Apart from that, they are pretty much left untouched.
Notes and thoughts
I must confess that I am new to Cabal 3; until last week I was using Cabal 1 (because I never bothered to update it; yes I know this is bad). With Cabal 1 I did not have any problem whatsoever, and I was perfectly able to install a package from local sources and depend on it in other projects...
I feel like I am doing something wrong; maybe am I not using the correct Cabal commands? I saw somewhere something about cabal new-build and cabal new-install but it does not seem to do anything more than cabal build and cabal install, at least in my case. I also wanted to investigate sandboxes but it seems that has disappeared since version 2 of Cabal.
There is also a slight possibility this is a Cabal bug, but I don't find any relevant issue on the bug tracker that may be related to my problem...
What do you think about this? What am I doing wrong? Do you see any alternative or possible fix?
Thanks a lot!
GHC environment files
A GHC installation comes with a certain number of packages out-of-the box. base is one of them but there are others, for example text. If you install GHC alone (no cabal or stack) and open ghci, it should let you import Data.Text without problems.
What if you want GHC or ghci to be aware of other compiled packages present in your filesystem? You can point GHC to additional package databases using command-line flags, but there's also the concept of package environment files.
Environments are plain text files that contain a list of package-related GHC flags. There might be a global environment at ~/.ghc/$ARCH-$OS-$GHCVER/environments/default, and there might also exist local environments which only affect GHC and ghci commands invoked inside the same folder. The exact rules for search are described in the GHC User Guide.
What does cabal install --lib actually do?
By default, it modifies the global environment file, so that GHC and ghci can now find that library. That's why point 3) worked. The actual compiled binaries of the library still reside in the cabal store though.
We can also create local environment files. For example cabal install sop-core --lib --package-env . will create the environment file .ghc.environment.xxx in the current folder, and the library will be available to ghc and ghci when they are invoked there.
Why isn't test1 available for test2?
Modern cabal makes a distinction between local packages and external packages.
local packages is the set of packages you are developing together in a project, being edited, recompiled and changed repeatedly. They are built "inplace" and not seen outside the project. They can depend on each other.
external packages are dependencies from build-depends: whose source code is downloaded from a package repository and which, when compiled, are put in the cabal store so that other Cabal projects might make use of them without re-compiling.
The list of local packages and other project-level configuration details are specified in a cabal.project file. But you don't need one if you work on a single isolated package; the default list of packages is simply ./*.cabal.
cabal wants to completely control the build environment of local packages, and will ignore the global environment file. In your case, you'll have to make test1 and test2 local packages in the same project (likely the best option) or publish test1 and treat it as an external package.
Note that "cabal project" is a concept relevant only during development. Packages are published independently, there are no "projects" in Hackage or other repositories, just packages.
What if I want to treat test1 as external without publishing it to Hackage?
You will have to set up a local package repository, basically a non-public Hackage.
You can tell Cabal about additional package repositories in the Cabal configuration file, that is, the file that configures cabal itself. Its location is given in the last line of cabal --help.
But how to set up the repository? The hackage-repo-tool can help with that.
Why did test3 fail? Why did further library installs fail?
That's weird, I have no idea why that happens. Did you by perchance delete the ~/.cabal folder between steps 3) and 5) ? What happens if you delete the global GHC environment file and try again?

Cabal: rebuild package to use newer libraries

I'm using Ubuntu 14.10 with GHC 7.6.3 and cabal installed via the Ubuntu package installer, and trying to use the Heap data structure, which I naively installed using:
cabal install heap
As soon as I started importing the library into my code, I got the following linking error:
...
Loading package primitive-0.5.0.1 ... linking ... done.
...
Loading package heap-1.0.0 ... linking ... done.
...
Loading package primitive-0.5.2.1 ... linking ... done
...
GHCi runtime linker: fatal error: I found a duplicate definition for symbol
hsprimitive_memset_Word32
whilst processing object file
/home/simon/.cabal/lib/primitive-0.5.2.1/ghc-7.6.3/HSprimitive-0.5.2.1.o
This could be caused by:
* Loading two different object files which export the same symbol
* Specifying the same object file twice on the GHCi command line
* An incorrect `package.conf' entry, causing some object to be
loaded twice.
GHCi cannot safely continue in this situation. Exiting now. Sorry.
This answer notionally explains what to do, but the instructions are not specific enough for me to follow.
How do I get Heap to use primitive-0.5.2.1 (I'm assuming that this lightly used library is the one that is out of date), or should I be doing something completely different?
One solution might be to specifically install an earlier version of heap:
cabal install heap-0.6.0
You might have to first unregister heap-1.0.0.
Another option is to blow away your ~/.ghc directory. Of course, you will have to reinstall cabal packages.
I think the best option is to start using cabal sandboxing for your projects.
Edit: heap-1.0.0 contains QuickCheck tests and thus brings in all of the QuickCheck dependencies. To install that version without QuickCheck, try this:
In a new directory, run cabal get heap-1.0.0
cd heap-1.0.0
Edit heap.cabal and remove the Build-Depends: line
Run cabal install

Haskell on Travis CI fails, passes locally

https://travis-ci.org/Fresheyeball/fbatch
Preprocessing library monad-parallel-0.5...
Control/Monad/Parallel.hs:67:8:
Could not find module `Control.Monad.Identity'
It is a member of the hidden package `mtl-2.2.1'.
Perhaps you need to add `mtl' to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
cabal: Error: some packages failed to install:
monad-parallel-0.5 failed during the building phase. The exception was:
ExitFailure 1
I am new to haskell, and just can't seem to get past this. I've tinkered with my .cabal file all I can, and the sub dependency fails on Travis every time.
Please help.
If a build fails while resolving a dependency, it's worth having a look a what version of that package gets installed. Normally, cabal should default to the most recent possible, which if well-maintained should install fine. Older versions do of course often mean trouble, if some dependency of theirs has now a newer, incompatible version installed.
In your case, cabal tried to install the somewhat ancient monad-parallel-0.5, which imports a module that doesn't exist in transformers (namely Control.Monad.Identity). The more recent version 0.7.1.2 does not try this and thus builds successfully. You can force such a recent install by giving a lower bound to the dependency in your .cabal file, in this case monad-parallel >= 0.7.

Minimal cabal file for use in sandbox

I’m trying to write a project with the Hakyll library. In order to avoid messing up with my system, I’d install it in a cabal sandbox in the same folder where my Hakyll project lives.
Being more or less a beginner, I’m still struggling with getting the pest practices right. A simple approach would be to just do
$ cabal sandbox init
$ cabal install hakyll
$ cabal exec ghc -- --make site.hs
where the last line compiles my Hakyll generator using the libraries in the sandbox. The obvious disadvantage is that this is not reproducible. The main version of Hakyll could have change when I try to run it again from a clean checkout.
Another approach would be to write a proper project.cabal file (For example like this: chromaticleaves.cabal) and then do cabal install or cabal run.
However, I feel that this may be a bit too much information. As I do not intend to publish this project any more than needed, I’m not really convinced I need to put a project name and version number in there. (For example, in a Ruby Gemfile, I would also only specify the libraries and nothing else unless I wanted to publish a gem myself.)
So, eventually I figured that with a file like
$ cat project.cabal
cabal-version: >= 1.2
library
build-depends: base >=4.6
, containers
, process
, hakyll >=4.5
, pandoc
, pandoc-types
I can type
$ cabal sandbox init
$ cabal install --only-dependencies
$ cabal exec ghc -- --make site.hs
and it seems to download all dependencies and is able to compile the file.
Is this a reasonable approach or is the best practice really to give a full specification with name, version and executable sections in the cabal file?
Edit: Apparently, my approach does not let me do cabal repl. So either there exists a completely different way of doing it or it seems I have to go with a fuller specification.
I use your first approach myself for my Hakyll-based webpage. You don't need to create a .cabal file to pin the Hakyll version, you only need to add the following line to cabal.config:
constraints: hakyll == 4.5
I think that cabal repl will work with this approach, but you will need to load site.hs manually (:l site.hs). Or you can use cabal exec ghci -- site.hs.

Pandoc 'Could not find module ...' for installed module

I'm currently trying to use pandoc (as a Haskell module, not as a program) to convert MediaWiki text to other formats.
Let's assume this program:
import Text.Pandoc.Readers.MediaWiki
main = do print "foo"
When using runghc to run it, I get the following error message:
pandock.hs:1:8:
Could not find module `Text.Pandoc.Readers.MediaWiki'
Use -v to see a list of the files searched for.
My first assumption was that pandoc was either not installed or incorrectly installed. Therefore I reinstalled it with --force-reinstalls
$ cabal install pandoc --reinstall
[...]
In order, the following will be installed:
pandoc-1.12.3.1 (reinstall) changes: old-time-1.1.0.1 added
[...]
[32 of 55] Compiling Text.Pandoc.Readers.MediaWiki ( src/Text/Pandoc/Readers/MediaWiki.hs, dist/build/Text/Pandoc/Readers/MediaWiki.o )
[...]
Installing library in
/home/uli/.cabal/lib/x86_64-linux-ghc-7.6.3/pandoc-1.12.3.1
Installing executable(s) in /home/uli/.cabal/bin
Registering pandoc-1.12.3.1...
Installed pandoc-1.12.3.1
The output of runghc -v pandock.hs is quite long, I assume the relevant part is:
*** Chasing dependencies:
Chasing modules from: *pandock.hs
pandock.hs:1:8:
Could not find module `Text.Pandoc.Readers.MediaWiki'
Locations searched:
Text/Pandoc/Readers/MediaWiki.hs
Text/Pandoc/Readers/MediaWiki.lhs
Failed, modules loaded: none.
However, both ~/.cabal/lib/x86_64-linux-ghc-7.6.3/pandoc-1.12.3.1/Text/Pandoc/Readers/Mediawiki/MediaWiki.hi and ~/.cabal/bin/pandoc exist. How can I make GHC properly recognize the cabal-installed package?
Any help will be appreciated!
When trying to reproduce this issue on other computers, only 2 out of 5 computers had this issue. On both of them I installed cabal packages in about the same way and order.
In retrospect I assume this issue arose because of some broken packages wreaking havoc:
$ ghc-pkg check
There are problems in package feed-0.3.9.2:
dependency "xml-1.3.13-dd52b1688e97a3c6cd0aa48dba7b153e" doesn't exist
There are problems in package hxt-9.3.1.3:
dependency "network-2.4.2.2-ea77cdf1bc747bc58308fdeb52745c4d" doesn't exist
There are problems in package hspec-1.8.1.1:
dependency "QuickCheck-2.6-409fcc32c191cd6e04afdebb15869820" doesn't exist
There are problems in package quickcheck-io-0.1.0:
dependency "QuickCheck-2.6-409fcc32c191cd6e04afdebb15869820" doesn't exist
There are problems in package regex-compat-0.95.1:
dependency "regex-base-0.93.2-2023953b859e6f91efe89733d2ef5421" doesn't exist
There are problems in package regex-posix-0.95.2:
dependency "regex-base-0.93.2-2023953b859e6f91efe89733d2ef5421" doesn't exist
There are problems in package hxt-9.3.1.2:
dependency "network-2.4.2.2-ea77cdf1bc747bc58308fdeb52745c4d" doesn't exist
The following packages are broken, either because they have a problem
listed above, or because they depend on a broken package.
feed-0.3.9.2
hxt-9.3.1.3
hspec-1.8.1.1
quickcheck-io-0.1.0
regex-compat-0.95.1
regex-posix-0.95.2
hxt-9.3.1.2
MissingH-1.2.0.2
yesod-test-1.2.1
Note that neither pandoc nor yaml (I installed it after asking the question and had the exact same issues as with pandoc) are listed there.
For users also having a similar problem, please ensure:
The package is installed and you're not inside any sandbox where the package is not installed.
In the directory where you're executing the test script, ensure that there is no Text/Pandoc folder (or equivalent, depending on the package causing the problem
Run your test script with runghc -v to check if it searches the proper directory
ghc-pkg list lists your package as installed, and no packages are broken (use ghc-pkg check to check)
I solved my problem by renaming ~/.cabal and ~/.ghc. Note that I did this lacking a proper solution, I think you should only do this as a last resort.

Resources