
I think the solution to this problem usually is to have a separate
source directory for each component of your package (library,
executable, test suite, etc). For example, put the library in 'src',
and the executable in 'exe'. This way source files won't mix, and the
executable can depend on the library in the same package, so that
source files are only compiled once.
I don't think a solution with all files in a single directory is
possible in general, since the executable might also need more source
files not included in the library.
Erik
On Wed, Sep 10, 2014 at 11:35 PM, Phil Ruffwind
It seems that even when invoked via Cabal, GHC will look in the local directory *first* and then in the list of modules and dependencies supplied by Cabal. I was aware of this behavior subconsciously but I hadn't realized the implications until now.
Normally, it's not a big problem, other than for the occasional situation where I forget to add those local modules to 'other-modules'. This would cause 'cabal sdist' to generate an incomplete package, even though 'cabal build && cabal install' works just fine!
But there are more subtle "bugs": it breaks if the executable and library share the same directory, but the library has some hidden modules stashed away in a different directory! The conditions required to reproduce this is somewhat difficult to explain, so let me show a simple example:
1. Make a Cabal package:
-- ./foo.cabal name: foo version: 0.0.0.0 build-type: Simple cabal-version: >=1.8 library exposed-modules: Exposed other-modules: Hidden build-depends: base hs-source-dirs: ., hidden executable main main-is: Main.hs build-depends: base, foo
2. Add a library with two modules at the given paths:
-- ./Exposed.hs module Exposed where import Hidden
-- ./hidden/Hidden.hs module Hidden where
3. Add an executable:
-- ./Main.hs module Main where import Exposed main = return ()
4. Now run `cabal build`. This would cause an error message akin to:
> Could not find module Hidden
The problem is that despite the dependency on the library `foo` being specified in Cabal, GHC still chose the *local* `Exposed` module over the `Exposed` module in the library `foo`. This means when it tries to recompile the `Exposed` module, it is unaware that `Hidden` is located in another directory.
The error message is unhelpful because it doesn't point to the actual cause of the problem and led me astray thinking that something was wrong with my Cabal configuration.
In the end, the problem has to do with GHC deciding to look up packages in locations outside Cabal's control. There are many other ways to trigger this problem -- the above was only one that I just happened to run into.
For now, a workaround would be to use `-i` with all the executables to avoid this subtle issue in the future.
RF _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe