Cabal: N executables without building all the modules N times?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Cabal: N executables without building all the modules N times?

James Cook-2
Hi libraries@,

(Let me know if there's a better place for Cabal questions. This list is
linked from https://www.haskell.org/cabal/ as a place to ask questions.)


I have a project with lots of modules, and lots of executables that use
those modules. How should I structure my .cabal file if I want cabal to
only build the common modules once?


I have found I can do it as follows, but I am wondering if there's a way
to do it without step 1:

1. Create a "library_src" directory with the source for all the shared
modules. Put the source files for the executables somewhere else.

2. Create a .cabal file with one "library" stanza with "hs-source-dirs:
library_source", and several executable stanzas.


If I leave out step 1 and put all the source files in the same place,
then the compiler builds them separately for each executable, and I get
a "missing-home-modules" warning.

Is it just a fact of life that I need to separate my source into
separate directories if I want this to work properly?


Here's a small example, with four files, where I left out step 1 (i.e.
put everything in the same directory). It does not behave the way I want
it to: it builds the Library module three times if I run "cabal
v2-build" and "cabal v2-test", and it shows the "missing-home-modules"
warning. It also still builds if I remove "mhm" from build-depends of
the executable and test-suite; I'd rather it failed to build if I did that.

mhm.cabal:

cabal-version: 2.2
name: mhm
version: 0

library
   exposed-modules: Library
   default-language: Haskell2010
   build-depends: base >=4.12 && <4.13

executable e
   main-is: e.hs
   build-depends: mhm, base >=4.12 && <4.13
   default-language: Haskell2010

test-suite t
   type: exitcode-stdio-1.0
   main-is: t.hs
   build-depends: mhm, base >=4.12 && <4.13
   default-language: Haskell2010


Library.hs:

module Library where

n :: Int
n = 5


e.hs:

module Main where

import Library

main = print n


t.hs:

module Main where

import Library

main = print n

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Cabal: N executables without building all the modules N times?

Haskell - Libraries mailing list
Hey James,

yes, if you want to avoid duplicate compilation, you need to define a `library` with a separate `hs-source-dirs` and use that library in the `build-depends` of your executables.

See

    https://stackoverflow.com/questions/12305970/how-to-make-a-haskell-cabal-project-with-libraryexecutables-that-still-run-with

and the linked question.

Cheers,
Niklas
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Cabal: N executables without building all the modules N times?

James Cook-2
On 2020-08-10 22:35, Niklas Hamb├╝chen wrote:

> Hey James,
>
> yes, if you want to avoid duplicate compilation, you need to define a `library` with a separate `hs-source-dirs` and use that library in the `build-depends` of your executables.
>
> See
>
>      https://stackoverflow.com/questions/12305970/how-to-make-a-haskell-cabal-project-with-libraryexecutables-that-still-run-with
>
> and the linked question.
>
> Cheers,
> Niklas

Thanks! That's exactly the information I was looking for. I guess I did
not use the right search terms.

--
James
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Cabal: N executables without building all the modules N times?

Henning Thielemann
In reply to this post by James Cook-2

On Mon, 10 Aug 2020, James Cook wrote:

> Hi libraries@,
>
> (Let me know if there's a better place for Cabal questions. This list is
> linked from https://www.haskell.org/cabal/ as a place to ask questions.)
>
>
> I have a project with lots of modules, and lots of executables that use
> those modules. How should I structure my .cabal file if I want cabal to
> only build the common modules once?
>
>
> I have found I can do it as follows, but I am wondering if there's a way
> to do it without step 1:
>
> 1. Create a "library_src" directory with the source for all the shared
> modules. Put the source files for the executables somewhere else.
>
> 2. Create a .cabal file with one "library" stanza with "hs-source-dirs:
> library_source", and several executable stanzas.

I use to setup directory 'src' for the library, 'test' for test code and,
say, 'example' for executables.

> If I leave out step 1 and put all the source files in the same place,
> then the compiler builds them separately for each executable, and I get
> a "missing-home-modules" warning.
>
> Is it just a fact of life that I need to separate my source into
> separate directories if I want this to work properly?

Yes. Problem is, that Cabal calls GHC's 'make' feature and that one
searches for appropriate modules in its search path.


Btw. you give a Library section a name you get a private sub-library of
private modules that can be shared between the public library and e.g. the
test suite.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries