2012-09-06 16 views
53

declare a library + executable sections in a cabal file while avoiding double compilation of the libraryライブラリをhs-source-dirsディレクトリに置くと、特に実行ファイルにヘルパーモジュールがある場合、通常はghcirunhaskellでプロジェクトを実行することはできません。runhaskell/ghciでまだ実行されているライブラリ+実行可能ファイルでHaskellカバールプロジェクトを作成するには?

  • だけ
  • 一度に必要とされるもの構築することをお勧めプロジェクトのレイアウトは何

    runhaskell

  • を使用することがハックせずにきれいな構造を有していることができますか?

答えて

84

はあなたがmylibライブラリを持っていると仮定しましょう、とmylib-commandlinemylib-server実行可能。

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 

スタブのようなそれぞれが二重のコンパイルを避け、自分のプロジェクトルートを持つように

あなたはライブラリと、各実行のためhs-source-dirsを使用しますエントリポイントファイルmylib-commandline/Main.hsは次のようになります。

module Main where 

import qualified Web.Mylib.Server.Main as MylibServer 

main :: IO() 
main = MylibServer.main 

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

あなたmylib.cabalは次のようになります。それぞれが自分のhs-source-dirsであると実行可能ファイルがライブラリに依存しているため

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つの実行を構築します。あなたはまだそれが(セパレータとして:を使用して)モジュールを探しならない場所を教えて-iスイッチを使用して、プロジェクトのルートからrunghcで実行可能ファイルを実行することができます

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

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

この方法は、あなたが持つことができますクリーンなレイアウト、ヘルパーモジュールを持つ実行ファイル、そしてすべてはまだrunhaskell/runghcghciで動作します。繰り返しこのフラグを入力しないようにするには、あなたの.ghciファイルに

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

に似た何かを追加することができます。


コードを別々のパッケージに分割する必要があります。 mylib,mylib-commandlineおよびmylib-server

+0

パーフェクトな答え、私は公式のハスケルページでこのような単純で直接的な記事を探していたが、運がない。おそらく、私は検索に十分な時間を費やさなかったかもしれませんが、これは私を助けました。ありがとうございました! – korCZis

3

cabal replを使用して、ghciをカバールファイルの設定で開始し、cabal runを実行して実行可能ファイルをコンパイルして実行することができます。runhaskellおよびghciとは異なり、cabal replおよびcabal runを使用すると、キャバレーのサンドボックスからの依存関係も正しく取得されます。

関連する問題