Skip to content

Reconsider how to specify dependencies on internal libraries #4155

Closed
@ezyang

Description

@ezyang

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:

  1. We define a new syntax for referring to internal libraries within a package. One possibility (to get the bikeshedding going): pkg/libname refers to the libname internal library of pkg. To refer to the current package, you can use a dot, as in ./libname, or the full package name.
  2. The build-depends syntax remains UNCHANGED. Instead, we augment the mixins syntax to accept qualified library names; e.g., mixins: foobar/helper, foobar/other-helper.
  3. Here is how module visibility works. As in Backpack today, if a library is mentioned in build-depends but not in mixins, 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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions