[Haskell-cafe] how do cabal internal libraries work?

Oleg Grenrus oleg.grenrus at iki.fi
Wed May 23 22:50:01 UTC 2018


Hi Evan,

the cure to your problem is to put source files of different components
into different directories. i.e.

testing.cabal:

library foo-internal
    hs-source-dirs: internal
    exposed-modules: Foo.Internal
    build-depends: base, text

library
    hs-source-dirs: public
    exposed-modules: Foo.Public
    build-depends: foo-internal, base

and file layout:

public/Foo/Public.hs
internal/Foo/Internal.hs

Even Cabal tells GHC that "Foo.Public" is the only module it need to
compile, GHC "discovers" ./Foo/Internal.hs and happily uses it.
There are other similar interactions because of that implicitness, I'd
advice to avoid having current directory "." (the default) in the
hs-source-dirs.

Hopefully this helps,

P.S. try "cabal check", it will tell you (among possible other things),
that to use internal libraries you need to specify "cabal-version: 2.0",
and there's actually an open ticket to add a check for you exact problem
(if components depend on each other *and* share a hs-source-dirs, it's a
bad idea - you will end up recompiling modules).

On 24.05.2018 01:09, Evan Laforge wrote:
> The example at
> https://www.haskell.org/cabal/users-guide/developing-packages.html#library
> doesn't seem to work as I expect.  The doc for the library field is
> out of date, but if you scroll down it mentions "internal libraries". 
> But depending on the internal library doesn't seem to have any effect,
> in that cabal still complains I didn't mention Foo.Internal, and
> doesn't see the build-depends from it.  Am I misinterpreting how the
> feature is supposed to work?
>
> This is with Cabal 2.2.0.1 and cabal-install 2.2.0.0, ghc 8.4.1:
>
> % cat testing.cabal
> name:           foo
> version:        1.0
> license:        BSD3
> cabal-version:  >= 1.23
> build-type:     Simple
>
> library foo-internal
>     exposed-modules: Foo.Internal
>     build-depends: base, text
>
> library
>     exposed-modules: Foo.Public
>     build-depends: foo-internal, base
>
> % cat Foo/Internal.hs
> module Foo.Internal where
> import Data.Text
>
> % cat Foo/Public.hs
> module Foo.Public where
> import Foo.Internal
>
> % cabal build
> Resolving dependencies...
> Configuring foo-1.0...
> Warning: Packages using 'cabal-version: >= 1.10' must specify the
> 'default-language' field for each component (e.g. Haskell98 or
> Haskell2010).
> If a component uses different languages in different modules then list the
> other ones in the 'other-languages' field.
> Preprocessing library 'foo-internal' for foo-1.0..
> Building library 'foo-internal' for foo-1.0..
> [1 of 1] Compiling Foo.Internal     ( Foo/Internal.hs,
> dist/build/foo-internal/Foo/Internal.o )
> [1 of 1] Compiling Foo.Internal     ( Foo/Internal.hs,
> dist/build/foo-internal/Foo/Internal.p_o )
> Preprocessing library for foo-1.0..
> Building library for foo-1.0..
>
> <no location info>: warning: [-Wmissing-home-modules]
>     These modules are needed for compilation but not listed in your
> .cabal file's other-modules: Foo.Internal
> [1 of 2] Compiling Foo.Internal     ( Foo/Internal.hs,
> dist/build/Foo/Internal.o )
>
> Foo/Internal.hs:2:1: error:
>     Could not find module ‘Data.Text’
>     Use -v to see a list of the files searched for.
>   |
> 2 | import Data.Text
>   | ^^^^^^^^^^^^^^^^
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20180524/8e86795b/attachment.sig>


More information about the Haskell-Cafe mailing list