Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Let's assume you have a <code>mylib</code> library, and <code>mylib-commandline</code> and <code>mylib-server</code> executables.</p> <p>You use <code>hs-source-dirs</code> for the library and each executable so that each has their own project root, avoiding double compilation:</p> <pre><code>mylib/ # Project root mylib.cabal src/ # Root for the library tests/ mylib-commandline/ # Root for the command line utility + helper modules mylib-server/ # Root for the web service + helper modules </code></pre> <p>Full directory layout:</p> <pre><code>mylib/ # Project root mylib.cabal src/ # Root for the library Web/ Mylib.hs # Main library module Mylib/ ModuleA # Mylib.ModuleA ModuleB # Mylib.ModuleB tests/ ... mylib-commandline/ # Root for the command line utility Main.hs # "module Main where" stub with "main = Web.Mylib.Commandline.Main.main" Web/ Mylib/ Commandline/ Main.hs # CLI entry point Arguments.hs # Programm command line arguments parser mylib-server/ # Root for the web service Server.hs # "module Main where" stub with "main = Web.Mylib.Server.Main.main" Web/ Mylib/ Server/ Main.hs # Server entry point Arguments.hs # Server command line arguments parser </code></pre> <p>The <em>stub-like</em> entry point file <code>mylib-commandline/Main.hs</code> looks like this:</p> <pre><code>module Main where import qualified Web.Mylib.Server.Main as MylibServer main :: IO () main = MylibServer.main </code></pre> <p>You need them because an <code>executable</code> must start on a module simply called <code>Main</code>.</p> <p>Your <code>mylib.cabal</code> looks like this:</p> <pre><code>library hs-source-dirs: src exposed-modules: Web.Mylib Web.Mylib.ModuleA Web.Mylib.ModuleB build-depends: base &gt;= 4 &amp;&amp; &lt;= 5 , [other dependencies of the library] executable mylib-commandline hs-source-dirs: mylib-commandline main-is: Main.hs other-modules: Web.Mylib.Commandline.Main Web.Mylib.Commandline.Arguments build-depends: base &gt;= 4 &amp;&amp; &lt;= 5 , mylib , [other depencencies for the CLI] executable mylib-server hs-source-dirs: mylib-server main-is: Server.hs other-modules: Web.Mylib.Server.Main build-depends: base &gt;= 4 &amp;&amp; &lt;= 5 , mylib , warp &gt;= X.X , [other dependencies for the server] </code></pre> <p><code>cabal build</code> will build the library and the two executables without double compilation of the library, because each is in their own <code>hs-source-dirs</code> and the executables depend on the library.</p> <p>You can still run the executables with <code>runghc</code> from your project root, using the <code>-i</code> switch to tell where it shall look for modules (using <code>:</code> as separator):</p> <pre><code>runhaskell -isrc:mylib-commandline mylib-commandline/Main.hs runhaskell -isrc:mylib-server mylib-server/Server.hs </code></pre> <p>This way, you can have a clean layout, executables with helper modules, and everything still works with <code>runhaskell</code>/<code>runghc</code> and <code>ghci</code>. To avoid typing this flag repeatedly, you can add something similar to</p> <pre><code>:set -isrc:mylib-commandline:mylib-server </code></pre> <p>to your <code>.ghci</code> file.</p> <hr> <p>Note that sometimes should split your code into separate packages, e.g. <code>mylib</code>, <code>mylib-commandline</code> and <code>mylib-server</code>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload