Description
Right now, if I define an internal library helper
in the package foobar
, I refer to it by adding an extra line to build-depends
:
name: foobar
version: 1.0
library helper
...
library
build-depends:
base >= 4.4,
helper
This is... kind of "wrong" from a semantic sense. There are two big reasons: (1) the primary reason that build-depends exist is to specify version bounds on external packages, but if we are referencing an internal library, you never want to actually specify a version bound: you want to refer to the library internally, and (2) we're clobbering the global namespace of packages, you can't name a helper the same name as an external package you also want to use.
We still have an opportunity to fix this, since internal libraries have not been published in a real release of Cabal. In particular, a new feature of Backpack might be a good way to fix this: the mixins
field. Here are the proposed new semantics:
- We define a new syntax for referring to internal libraries within a package. One possibility (to get the bikeshedding going):
pkg/libname
refers to thelibname
internal library ofpkg
. To refer to the current package, you can use a dot, as in./libname
, or the full package name. - The
build-depends
syntax remains UNCHANGED. Instead, we augment themixins
syntax to accept qualified library names; e.g.,mixins: foobar/helper, foobar/other-helper
. - Here is how module visibility works. As in Backpack today, if a library is mentioned in
build-depends
but not inmixins
, we do the historical behavior: the public library of that package is brought into scope. Otherwise, if ANY mixin refers to a package, we no longer bring that into scope; we bring precisely only the libraries identified by mixins into scope. So for example:
name: foobar
library
...
library helper
...
executable fooexe
build-depends: foobar
mixins: foobar/helper
this package only brings the modules of helper
into scope for fooexe
, not the main library foobar
. (BY THE WAY, if we hate the fact that referring to a package via a mixin causes its default "import" to not be brought into scope, we could add a new variant of build-depends
for packages we want to depend on, but should not have any modules brought into scope; maybe just version-depends
?)
4. Optionally, we can make it optional to specify the name of the current package in build-depends if you want to use libraries from it in mixins. So continuing the example from above,
name: foobar
library
...
executable fooexe
mixins: foobar/helper
is OK (you can omit the build-depends
.) This is a bit clearer. If we ever end up supporting multiple public libraries per package, you'll have to specify that package in build-depends (since we need to know to depsolve for it, and what your version constraints are.)
CC @Ericson2314