*.conf files and executable stanzas of Cabal files

I have a simple two-package project (A, B) and the Cabal file for packageB has only an executable stanza, which depends on packageA:

cabal-version: 1.12
name:           packageB
version:        0.1.0.0
build-type:     Simple

executable packageB
  main-is: Main.hs
  hs-source-dirs:
      app
  ghc-options: -threaded -rtsopts -with-rtsopts=-N
  build-depends:
      base >=4.7 && <5
    , packageA
  default-language: Haskell2010

When Stack builds that project, there is no installed packageB: stack exec -- ghc-pkg list (extracts):

C:\Users\mikep\Documents\Code\Haskell\multiTest\.stack-work\install\c3501600\pkgdb
    packageA-0.1.0.0

Is that the expected behaviour? Would Cabal (the tool) do something different?

If I do add a library stanza to packageB, the depends: field of the resulting installed package (stack exec -- ghc-pkg field packageB depends) excludes the dependencies of the executable stanza:

depends: base-4.17.2.0

Again, is that the expected behaviour? Would Cabal (the tool) do something different?

EDIT: The motivation for this question is that Stack ‘agressively unregisters’ installed local/mutable packages to ensure that things are rebuilt when source files are ‘dirty’, but that only works if ghc-pkg dump will yield the dependencies of such packages. It looks to me like dependencies of executable stanzas are omitted from *.conf files.

1 Like

On the corresponding behaviour of Cabal, I think the answers are: it would do the same.

That is based on an experiment with a cabal.project file and stack exec --no-ghc-package-path -- cabal install all, and looking at the build artefacts in the dist-newstyle directories.

Why would there be a package? The only thing that exists is an executable, not a library. I’m not sure what a package with only an executable would be? You wouldn’t be able to link against it or anything, after all it’s just an executable. A final leaf node of your build?

I certainly wouldn’t expect anything non-library-like to become an installed package. I also wouldn’t know what an installed package of such would mean? We don’t install executable into the package-db.

I assume it’s better to think of the .cabal file for an executable only as just that, and executable, not a reusable component. Whereas a cabal file that includes a library constitutes a package that may be re-used (by potentially even an executable in the same .cabal file).

I don’t think there is anything to unregister from executables only. Cabal (used to?) put them into ~/.cabal/bin/; so you could unlink them there?

1 Like

Thanks. I have also found in the Cabal Guide 3.2.3 about ‘GHC packages’: “GHC only cares about library packages, not executables.”.

The underlying Stack problem is that when a local package is rebuilt, Stack has to decide what other local packages in the same project need to be rebuilt. It has been making use of the depends: field in *.conf files to identify relevant relationships, but that does not work for non-library stanzas. I am still getting to the bottom of what Stack, in fact, does and why.

1 Like

If you haven’t already seen it, I found https://www.youtube.com/watch?v=XfTinQPjDQw very informative! You can also jump to this particular slide https://haskell.foundation/assets/other/Duncan%20Coutts%20-%20GHC%20Tool%20Ecosystem.pdf#page=12 which at least notes that the “package database” really is only about libraries.

The commentary during the talk about terminology was also helpful: “package” has multiple meanings unfortunately.

2 Likes