Как сделать проект Haskell cabal с библиотекой + исполняемыми файлами, которые все еще работают с runhaskell/ghci?



если вы объявить библиотеку + исполняемые разделы в файле cabal, избегая двойной компиляции библиотеки поместив библиотеку в hs-source-dirs каталог, вы обычно не можете запустить свой проект с ghci и runhaskell больше, особенно если исполняемые файлы имеют вспомогательные модули.



что такое рекомендуемый макет проекта, который




  • только строит то, что нужно после

  • позволяет использовать runhaskell

  • имеет чистую структуру без хаков?

576   2  

2 ответов:

предположим, что у вас есть 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

The stub-like файл точки входа 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 построит библиотеку и два исполняемых файла без двойной компиляции библиотеки, потому что каждый находится в своем собственном hs-source-dirs и исполняемые файлы зависят от библиотеки.

вы все еще можете запускать исполняемые файлы с runghc из корня проекта, используя -i переключитесь, чтобы сказать, где он должен искать модули (используя : в качестве разделителя):

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

на .


обратите внимание, что иногда следует разделить код на отдельные пакеты, например mylib,mylib-commandline и mylib-server.

можно использовать cabal repl чтобы запустить ghci с конфигурацией из файла cabal и cabal run для компиляции и запуска исполняемых файлов. В отличие от runhaskell и ghci, используя cabal repl и cabal run также правильно подбирает зависимости из песочниц cabal.

Comments

    Ничего не найдено.