web-dev-qa-db-ja.com

runhaskell / ghciでまだ実行されているライブラリ+実行可能ファイルを使用してHaskellcabalプロジェクトを作成するにはどうすればよいですか?

ライブラリの二重コンパイルを回避しながら、ライブラリ+実行可能セクションをcabalファイルで宣言する ライブラリをhs-source-dirsディレクトリに配置する場合、通常はghcirunhaskellは、特に実行可能ファイル自体にヘルパーモジュールがある場合はもうありません。

推奨されるプロジェクトレイアウトは何ですか

  • 必要なものを一度だけ構築する
  • runhaskellの使用を許可します
  • ハッキングのないきれいな構造を持っていますか?
55
nh2

mylibライブラリと、mylib-commandlineおよびmylib-server実行可能ファイルがあると仮定します。

ライブラリと各実行可能ファイルにhs-source-dirsを使用して、それぞれが独自のプロジェクトルートを持ち、二重コンパイルを回避します。

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

完全なディレクトリレイアウト:

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

スタブのようなエントリポイントファイルmylib-commandline/Main.hsは次のようになります。

module Main where

import qualified Web.Mylib.Server.Main as MylibServer

main :: IO ()
main = MylibServer.main

executableは単にMainと呼ばれるモジュールで開始する必要があるため、これらが必要です。

mylib.cabalは次のようになります:

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は、ライブラリと2つの実行可能ファイルをビルドします。これは、それぞれが独自のhs-source-dirsにあり、実行可能ファイルがライブラリに依存しているためです。

-iスイッチを使用してモジュールを探す場所を指定し(セパレータとして:を使用)、プロジェクトルートからrunghcを使用して実行可能ファイルを実行できます。

runhaskell -isrc:mylib-commandline mylib-commandline/Main.hs

runhaskell -isrc:mylib-server mylib-server/Server.hs

このようにして、クリーンなレイアウト、ヘルパーモジュールを備えた実行可能ファイルを作成でき、すべてがrunhaskell/runghcおよびghciで引き続き機能します。このフラグを繰り返し入力しないようにするには、次のようなものを追加します。

:set -isrc:mylib-commandline:mylib-server

.ghciファイルに。


コードを個別のパッケージに分割する必要がある場合があることに注意してください。 mylibmylib-commandlineおよびmylib-server

86
nh2

cabal replを使用してcabalファイルの構成でghciを開始し、cabal runを使用して実行可能ファイルをコンパイルして実行できます。 runhaskellおよびghciとは異なり、cabal replおよびcabal runを使用すると、陰謀団のサンドボックスから依存関係も正しく取得されます。

3
Toxaris