If you declare a library + executable sections in a cabal file while avoiding double compilation of the library by putting the library into a hs-source-dirs directory, you cannot usually run your project with ghci and runhaskell anymore, especially if the executables have helper modules themselves.
What is a recommended project layout that
- only builds what is needed once
- allows using
runhaskell - has a clean structure without hacks?
Let’s assume you have a
myliblibrary, andmylib-commandlineandmylib-serverexecutables.You use
hs-source-dirsfor the library and each executable so that each has their own project root, avoiding double compilation:Full directory layout:
The stub-like entry point file
mylib-commandline/Main.hslooks like this:You need them because an
executablemust start on a module simply calledMain.Your
mylib.caballooks like this:cabal buildwill build the library and the two executables without double compilation of the library, because each is in their ownhs-source-dirsand the executables depend on the library.You can still run the executables with
runghcfrom your project root, using the-iswitch to tell where it shall look for modules (using:as separator):This way, you can have a clean layout, executables with helper modules, and everything still works with
runhaskell/runghcandghci. To avoid typing this flag repeatedly, you can add something similar toto your
.ghcifile.Note that sometimes should split your code into separate packages, e.g.
mylib,mylib-commandlineandmylib-server.