Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle internal libraries correctly #539

Open
sternenseemann opened this issue Jan 22, 2022 · 5 comments
Open

Handle internal libraries correctly #539

sternenseemann opened this issue Jan 22, 2022 · 5 comments
Milestone

Comments

@sternenseemann
Copy link
Member

sternenseemann commented Jan 22, 2022

Since 2.0, Cabal has a notion of internal libraries (which is any named library in the cabal file):

Cabal 2.0 and later support “internal libraries”, which are extra named libraries (as opposed to the usual unnamed library section). […]

Internal libraries are also useful for packages that define multiple executables, but do not define a publicly accessible library. Internal libraries are only visible internally in the package (so they can only be added to the build-depends of same-package libraries, executables, test suites, etc.) Internal libraries locally shadow any packages which have the same name; consequently, don’t name an internal library with the same name as an external dependency if you need to be able to refer to the external dependency in a build-depends declaration.

My intuition would be that we'd need to detect these and disable the internal library (i.e. setting isLibrary = false; in simple cases). An obvious example of this is jacinda which has an executable and an internal library we should not install.

It gets trickier if you have an internal library (e.g. for the test suite and executable) and a public library. We probably need to teach the generic-builder.nix in nixpkgs to distinguish between public and internal library instead of relying on isLibrary (which should only describe whether we have a public library or not).

What is a bit unclear to me is whether a public library can depend on an internal one and if we would need to install the internal one in such cases.

See also NixOS/nixpkgs#155924 (comment).

@m4dc4p
Copy link

m4dc4p commented Feb 4, 2022

Not as obvious, but this bug leads to huge closure sizes (such as including all of GHC and its docs). Especially painful when using nix to build docker images.

@maralorn
Copy link
Member

maralorn commented Feb 5, 2022

@m4dc4p You mean this affects packages which have only executables and internal libraries?

Note that you can currently work around this by applying the function haskell.lib.justStaticExecutables to the resulting packages.

@sternenseemann
Copy link
Member Author

I'm still inclined to think that this is a Cabal bug as well, Setup.hs copy should not install things that are not supposed to be installed.

@m4dc4p
Copy link

m4dc4p commented Feb 5, 2022

@maralorn That doesn't work when the executable also includes an internal library. (We were already using the justStaticExecutables function). Moving the executables to their own package does work, however, if the shared library uses the Cabal data-files feature, you still end up with a closure that depends on GHC. See NixOS/nixpkgs#155924 (comment).

@TeofilC
Copy link

TeofilC commented Oct 23, 2023

I took a brief look at this and testing it locally it seems that both Setup copy <exe component> and Setup install install the internal library even if we just pass the name of an exe component that depends on it. So I think #539 (comment) is right that this is a Cabal bug.
Edit: I took another look at this and managed to get it working, ie, only the correct components were installed by ./Setup.

In this comment: #603 (comment) @sternenseemann, you suggested that there should be a way forward that makes better use of component info. What did you have in mind?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants