Reputation: 27225
I used the default stack new
to setup a project that has a server and a client as separate executables. I altered the package.yaml
file in what seems like the right way (As of April 21, 2020 "There is no user guide") and added a new file to my app
directory called Client.hs
.
I got an error saying "Enabling workaround for Main module 'Main' listed in 'other-modules' illegally!"
How do I have stack build both the client and the server?
When I ran stack build
I got:
[... 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
The relevant portion of package.yaml
looks like this:
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
Upvotes: 6
Views: 1553
Reputation: 285
For me the solution by K. A. Buhr didn't work. If I put a module name that doesn't match the file such as the proposed
-- in Client.hs
module Main where
I get the error "File name does not match module name". I also can't call the file Main.hs because there is already another file called Main.hs.
The only way to solve this was to use
-- in Client.hs
module Client where
add the lines other-modules: []
and - -main-is Client
to the package.yaml:
executables:
ObjectServer:
main: Main.hs
other-modules: []
source-dirs: app
ghc-options:
- -threaded
- -main-is Main
dependencies:
- ObjectServer
Client:
main: Client.hs
other-modules: []
source-dirs: app
ghc-options:
- -threaded
- -main-is Client
dependencies:
- ObjectServer
Upvotes: 1
Reputation: 51109
There are two problems here. First, the default value for other-modules
in hpack
is "all modules in source-dirs
except main
and modules mentioned in a when
clause". If you look at the generated .cabal
file, you'll see that as a result of this default, each executable has incorrectly included the other executable's module in its other-modules
list. Second, the main
setting gives the source file that contains the main module, but doesn't change the name of the module expected by GHC from Main
to anything else. Therefore, that module still needs to be named module Main where ...
, not module Client where...
, unless you also, separately add a -main-is Client
GHC option.
So, I would advise modifying Client.hs
to make it the Main
module:
-- in Client.hs
module Main where
...
and then specifying other-modules: []
explicitly for both executables:
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
That seems to work in my testing.
Upvotes: 7