Nehmen wir an, Sie eine mylib
Bibliothek haben, und mylib-commandline
und mylib-server
ausführbare Dateien.
Sie verwenden hs-source-dirs
für die Bibliothek und jede ausführbare Datei, so dass jede ihr eigenes Projekt Wurzel hat, doppelte Kompilation zu vermeiden:
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
Vollverzeichnisstruktur:
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
Der zapfenförmige Einstiegspunkt Datei mylib-commandline/Main.hs
sieht so aus:
module Main where
import qualified Web.Mylib.Server.Main as MylibServer
main :: IO()
main = MylibServer.main
Sie benötigen sie, weil ein executable
auf einem Modul mit dem Namen Main
gestartet werden muss.
Ihre mylib.cabal
sieht wie folgt aus:
library
hs-source-dirs: src
exposed-modules:
Web.Mylib
Web.Mylib.ModuleA
Web.Mylib.ModuleB
build-depends:
base >= 4 && <= 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 >= 4 && <= 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 >= 4 && <= 5
, mylib
, warp >= X.X
, [other dependencies for the server]
cabal build
wird die Bibliothek und die beiden ausführbaren Dateien ohne doppelte Erstellung der Bibliothek bauen, weil jede in ihrem eigenen hs-source-dirs
ist und die ausführbaren Dateien hängen von der Bibliothek.
Sie können immer noch die ausführbaren Dateien mit runghc
aus dem Projekt root ausführen, mit dem -i
Schalter zu sagen, wo es für die Module aussehen soll (mit :
als Trennzeichen):
runhaskell -isrc:mylib-commandline mylib-commandline/Main.hs
runhaskell -isrc:mylib-server mylib-server/Server.hs
Auf diese Weise können Sie eine haben sauberes Layout, ausführbare Dateien mit Hilfsmodulen, und alles funktioniert immer noch mit runhaskell
/runghc
und ghci
. Zur Vermeidung dieses Flag Eingabe wiederholt, können Sie etwas Ähnliches wie
:set -isrc:mylib-commandline:mylib-server
auf Ihre .ghci
Datei hinzufügen.
Beachten Sie, dass manchmal Ihren Code in separate Pakete, z. mylib
, mylib-commandline
und mylib-server
.
Perfekte Antwort, ich war auf der Suche nach solchen einfachen und geradlinigen Artikel auf offiziellen Haskell Pages, aber ohne Glück. Wahrscheinlich habe ich nicht genug Zeit mit der Suche verbracht, aber das hat mir sehr geholfen. Vielen Dank! – korCZis