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

James Cook falsifian at falsifian.org
Mon Aug 10 19:38:45 UTC 2020


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



More information about the Libraries mailing list