how do cabal internal libraries work?

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 | ^^^^^^^^^^^^^^^^

Do you get the same error if you give each library a different
hs-source-dir ?
I don't know the actual reason, but I would guess that maybe something
funny is happening with all of the modules being in the same folder.
Just a guess which is probably wrong! Hope it helps! :)
On Thu, 24 May 2018, 08:10 Evan Laforge,
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.

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.

On Wed, May 23, 2018 at 3:50 PM, Oleg Grenrus
Hi Evan,
the cure to your problem is to put source files of different components into different directories. i.e.
Yes, that's exactly it! Thanks for the explanation.
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.
Indeed, though it's an awkward and surprising limitation, to me at least. I would think ghc would be looking for dist/build/library/Foo/Internal.hi, and not find it. I assume it has to do with ghc --make is sort of a build system, and cabal is sort of a build system, and they sort of cooperate with each other :)
participants (3)
-
Ben Kolera
-
Evan Laforge
-
Oleg Grenrus