在默认的Haskell Stack项目中构建多个可执行文件



我使用默认的stack new来设置一个项目,该项目将服务器和客户端作为单独的可执行文件。我以正确的方式修改了package.yaml文件(截至2020年4月21日"没有用户指南"(,并在我的app目录中添加了一个名为Client.hs的新文件。

我收到一个错误,说"为‘其他模块’中非法列出的主模块‘Main’启用变通方法!">

如何让堆栈同时构建客户端和服务器?

当我运行stack build时,我得到了:

[... clip ...]
Building executable 'ObjectServer' for ObjectServer-0.1.0.1..
[4 of 4] Compiling Client
Linking .stack-workdist29cc6475buildObjectServerObjectServer.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:HaskellStacksetup-exe-cachex86_64-windowsCabal-simple_Z6RU0evB_3.0.1.0_ghc-8.8.3.exe --builddir=.stack-workdist29cc6475 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

这里有两个问题。首先,hpackother-modules的默认值为"source-dirs中除mainwhen子句中提到的模块外的所有模块"。如果查看生成的.cabal文件,您会发现由于此默认设置,每个可执行文件都错误地将另一个可执行文件的模块包含在其other-modules列表中。其次,main设置提供了包含主模块的源文件,但不会将GHC期望的模块名称从Main更改为其他任何名称。因此,模块仍然需要命名为module Main where ...,而不是module Client where...,除非您还单独添加了-main-is ClientGHC选项。

因此,我建议修改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

这在我的测试中似乎有效。

最新更新