Создание нескольких исполняемых файлов в проекте Haskell Stack по умолчанию
Я использовал по умолчанию stack new
для настройки проекта, в котором сервер и клиент являются отдельными исполняемыми файлами. Я изменилpackage.yaml
файл, который кажется правильным (по состоянию на 21 апреля 2020 г. "Руководства пользователя нет"), и добавил новый файл в моюapp
каталог называется Client.hs
.
Я получил сообщение об ошибке: "Включение обходного пути для основного модуля Main, указанного в списке other-modules, незаконно!"
Как сделать так, чтобы стек собирал как клиент, так и сервер?
Когда я бежал stack build
Я получил:
[... clip ...]
Building executable 'ObjectServer' for ObjectServer-0.1.0.1..
[4 of 4] Compiling Client
Linking .stack-work\dist\29cc6475\build\ObjectServer\ObjectServer.exe ...
Warning: Enabling workaround for Main module 'Main' listed in 'other-modules'
illegally!
Preprocessing executable 'Client' for ObjectServer-0.1.0.1..
Building executable 'Client' for ObjectServer-0.1.0.1..
[3 of 3] Compiling Client
<no location info>: error:
output was redirected with -o, but no output will be generated
because there is no Main module.
-- While building package ObjectServer-0.1.0.1 using:
D:\HaskellStack\setup-exe-cache\x86_64-windows\Cabal-simple_Z6RU0evB_3.0.1.0_ghc-8.8.3.exe --builddir=.stack-work\dist\29cc6475 build lib:ObjectServer exe:Client exe:ObjectServer --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
Соответствующая часть package.yaml
выглядит так:
executables:
ObjectServer:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- ObjectServer
Client:
main: Client.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- ObjectServer
1 ответ
Здесь есть две проблемы. Во-первых, значение по умолчанию дляother-modules
в hpack
"все модули в source-dirs
Кроме main
и модули, упомянутые в when
предложение ". Если вы посмотрите на сгенерированный .cabal
файла, вы увидите, что в результате этого значения по умолчанию каждый исполняемый файл неправильно включил модуль другого исполняемого файла в свой other-modules
список. Во-вторых,main
параметр дает исходный файл, содержащий основной модуль, но не меняет имя модуля, ожидаемого GHC от Main
ни к чему другому. Следовательно, этот модуль все еще необходимо назватьmodule Main where ...
не module Client where...
, если вы тоже не добавляете отдельно -main-is Client
Вариант GHC.
Итак, я бы посоветовал изменить Client.hs
сделать это Main
модуль:
-- in Client.hs
module Main where
...
а затем указав other-modules: []
явно для обоих исполняемых файлов:
executables:
ObjectServer:
main: Main.hs
other-modules: []
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- ObjectServer
Client:
main: Client.hs
other-modules: []
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- ObjectServer
Похоже, это работает в моем тестировании.