Many near identical copies of packages in .cabal/store

My .cabal/store/ghc-9.4.8 contains a few near-duplicates, such as:

vector-hashtables-0.1.1.4-c4e4bc400f877c15cf1884beb14a9ba4321ec318deab68c75ac446eb2cfcd533
vector-hashtables-0.1.1.4-e2a27d7d2f3f722888dd0258c0b7539c978f115805501c197cb9e621d7ea4c45
vector-hashtables-0.1.2.0-c2ab4c364abc503ce05f67a2e0967f211cc029ebf77854e6ed28e59ee1f9c683
vector-hashtables-0.1.2.0-d005f9e2949631c2416298798bb8976a17b2b17e7179f4cb457790883bdf4417

I can understand why there are distinct versions of the package but why do I have multiple folders with the same package numbers?

Additionally, cabal list --installed does not show this package. Neither is it displayed by ghc-pkg-9.4.8 list. So, is there a way for me to tell what depends on this?

Under what circumstances is it safe for me to delete directories here without breaking other packages?

2 Likes

If you ‑or a dependency - have built vector-hashtables with different build options, it will result in different build artefacts (optimisation flags for instance). The hash after the version can be understood as a summary of the build options that were used for the library, and so if you use the same options, cabal will be able to reuse the compiled artefacts safely.

Here you have 4 directories because there are two versions (0.1.1.4 and 0.1.20), which have been compiled with two sets of options.

2 Likes

Is there a specification of what exactly constitutes the hash?

I am not sure whether it qualifies as a specification or not but the code is in Distribution.Client.PackageHash.

cabal/cabal-install/src/Distribution/Client/PackageHash.hs at d037ce797717f878505a5e95768c894d611a409c · haskell/cabal · GitHub.

Also note that the (human readable) pre-image of the hash is stored in the file cabal-hash.txt along with the compiled code. Use this to investigate the difference between two builds.

λ sha256sum ~/.local/state/cabal/store/ghc-9.8.2/vector-0.13.1.0-ada151120551373fda94c004b4d35a0d9e5f30219b2fdd3f3fc410928cc5e675/cabal-hash.txt
ada151120551373fda94c004b4d35a0d9e5f30219b2fdd3f3fc410928cc5e675  /home/andrea/.local/state/cabal/store/ghc-9.8.2/vector-0.13.1.0-ada151120551373fda94c004b4d35a0d9e5f30219b2fdd3f3fc410928cc5e675/cabal-hash.txt

λ cat ~/.local/state/cabal/store/ghc-9.8.2/vector-0.13.1.0-ada151120551373fda94c004b4d35a0d9e5f30219b2fdd3f3fc410928cc5e675/cabal-hash.txt
pkgid: vector-0.13.1.0
component: ComponentLib
src: 63f272279eab8ab9411a0fffb1252ac309b297313f8e33be9ebbc2f981edecee
pkg-config-deps:
deps: base-4.19.1.0-cbb2, deepseq-1.5.0.0-d161, primitive-0.9.0.0-6dc10df24e1851bf7f58d8248d23ae45f040e71b7d2eec5124722b5156b6f8d1, vector-stream-0.1.0.1-9461937fdb822c95a616f578be7036f9c894fd40efb55635712b55b82bb60950
compilerid: ghc-9.8.2
platform: x86_64-linux
flags: +boundschecks -internalchecks -unsafechecks -wall
shared-lib: True
stripped-exe: False
debug-info: 0
3 Likes

TIL about cabal list --installed. It looks to list globally installed packages in the user package-db, which is not something that cabal “v2” commands do anymore. Maybe it should be renamed to v1-list to make this distinction clear.

Somewhat similarly ghc-pkg-9.4.8 list will list the content of the global and user package-db; while the store lives in a separate place. You can point it to the store though: ghc-pkg list --package-db ~/.cabal/store/ghc-9.4.8/package.db.

3 Likes

That looks like optimization level or any other ghc option is not part of the hash?

pkgHashOptimization :: OptimisationLevel is part of PackageHashConfigInputs (which is part of PackageHashInputs).

Ah, so the contents of cabal-hash.txt are just incomplete?

Nothing is just. Default values are not rendered to avoid mass-recompilation when a new field is added. See this note.

2 Likes

More common than different build options, I think, is different dependencies. If you compile foo-1 against bar-1, foo-1 will get a particular hash, and then if you cabal update and compile foo-1 against bar-2, foo-1 will get a different hash.

An easy thing to do is to delete all of .cabal. That means that you’ll have to rebuild all your dependencies the next time you compile anything, but if .cabal is getting very big it can be worth it.

2 Likes

Rarely I had success removing single entries from the store. You could try to use ghc-pkg check to see what dependencies are broken. NOTE: AFAIR cabal-install assume the store is consistent, if you accidentally break dependencies, cabal-install will have hard time.

2 Likes