Building multiple executables in the default Haskell Stack project - haskell

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

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.

Related

How to get a graph of dependencies of Haskell project

I have a several executable targets in the project, like:
...
app/
other_app/
src/
package.yaml
stack.yaml
...
so, I have obviously different .hs files in app/, other_app/, src/. If I build it with stack tool then it build apps and other_apps executables from their dependencies, ie, if some .hs file changed in src/ - the result executable will be rebuild. Otherwise - no. stack knows a graph of dependencies like GNU make does it. How to list/print this graph? For example, for C I have makedepend tool which is able to extract dependencies recursively from .c files. Is it possible to be done for Haskell files? With stack tool itself? Maybe with a cabal tool? I tried, for example, v2-freeze of the cabal tool, but it is not related to the problem.
UPDATE:
package.yaml looks like:
.............
executables:
app1-exe:
main: Main.hs
source-dirs: app1
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- app1
app2-exe:
main: Main.hs
source-dirs: app2
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- app1
............
and now I want to list recursively dependencies (in Makefile-style, not dependencies on packages, like stack dot does it!), for instance for app2's Main.hs, something like:
src/Component1/Types.hs
src/Component1/Utils.hs
src/CoolLibrary/CoolUtility.hs
...

Adding dependencies to stack project

I am very new to Haskell and I am trying to add the graphics package gloss to my stack project but I am encountering problems when doing stack build.
I have created my stack project as follows:
LICENSE package.yaml stack.yaml
README.md package.yaml~ stack.yaml.lock
Setup.hs project39.cabal stack.yaml~
TAGS project39.cabal~ test
and edited the stack.yamland the cabal file as follows:
# extra-deps:
# - acme-missiles-0.3
# - git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# - gloss-1.13.2.1
executable project39-exe
main-is: Main.hs
other-modules:
Paths_project39
hs-source-dirs:
app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
, project39
, gloss
default-language: Haskell2010
In the src file Lib.hs I have added a Import Graphics.Gloss to test if it works:
module Lib
( someFunc
) where
import Graphics.Gloss
but when I then do stack build I get the following error:
Could not load module ‘Graphics.Gloss’
It is a member of the hidden package ‘gloss-1.13.2.1’.
Perhaps you need to add ‘gloss’ to the build-depends in your .cabal file.
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
4 | import Graphics.Gloss
| ^^^^^^^^^^^^^^^^^^^^^
I am unsure what the problem here is and how to solve it.
You have a separate library stanza in your package.yaml. You need to add the gloss dependency there.

file descriptor out of range for select - Recompile with -threaded to work around this

I had a Haskell application crash today with this error message:
app: file descriptor 8758616 out of range for select (0--1024).
Recompile with -threaded to work around this.
How can I solve this? What does -threaded mean?
-threaded refers to the option passed to GHC.
If using hpack you can specify it like this:
executables:
app:
source-dirs: src
main: Main.hs
ghc-options: [-threaded]
(couldn't find any reasonable answer for this error on the first page of Google - hence this post).

Unable to add classy-prelude dependency

I am trying to add classy-prelude dependency to my stack project as follows:
name: FooService
version: 0.1.0.0
github: "githubuser/FooService"
license: BSD3
author: "Author name here"
maintainer: "example#example.com"
copyright: "2019 Author name here"
extra-source-files:
- README.md
- ChangeLog.md
# Metadata used when publishing your package
# synopsis: Short description of your package
# category: Web
# To avoid duplicated efforts in documentation and dealing with the
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description: Please see the README on GitHub at <https://github.com/githubuser/FooService#readme>
dependencies:
- base >= 4.7 && < 5
- classy-prelude
default-extesion:
- NoImplicitPrelude
- OverloadedStrings
library:
source-dirs: src
executables:
FooService-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- FooService
tests:
FooService-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- FooService
when call the interactive environment I've got the error message:
Using main module: 1. Package `FooService' component FooService:exe:FooService-exe with main-is file: /home/developer/haskell/FooService/app/Main.hs Cabal file info not found for classy-prelude-1.5.0#sha256:ed1a607f688745bc263be0b2ed2492729a62fd4c9821b68c2bfacbd7a9d9293d,1928, updating Selected mirror https://s3.amazonaws.com/hackage.fpcomplete.com/ Downloading timestamp No package index update available, but didn't update cache last time, running now Calculating hashes to check for hackage-security rebases or filesystem changes Updating preexisting cache, should be quick Populating cache from file size 640326144, hash bb56d41c70c9e6cdd625a6c3c7de5f56823e92cc6fe880f8056259ab31d3e0d5 Populating package index cache ... Failed populating package index cache
Error: BadChecksum 0
Warning: Build failed, but trying to launch GHCi anyway The following GHC options are incompatible with GHCi and have not been passed to it:
-threaded Configuring GHCi with the following packages: FooService GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help <command line>: cannot satisfy -package classy-prelude-1.5.0
What is missing?

How to define multiple executables / Main modules with stack/hpack

I use stack and a package.yaml file for hpack to compile my haskell project. It has three executables backed by one library. As one would expect the executables are all defining a Main module:
$ head -n1 app/*
==> app/Foo.hs <==
module Main where
==> app/Bar.hs <==
module Main where
==> app/Baz.hs <==
module Main where
And I use this package.yaml which looks very similar (to me) to the one linked from the official docs for hpack (the third one).
name: myproject
dependencies:
- base
library:
source-dirs: src
executables:
foo:
main: Foo.hs
source-dirs: app
dependencies: myproject
bar:
main: Bar.hs
source-dirs: app
dependencies: myproject
baz:
main: Baz.hs
source-dirs: app
dependencies: myproject
But when I stack build I get the error, that the module name does not match
the file name:
Building all executables for `myproject' once. After a successful build of all of them, only specified executables will be rebuilt.
myproject-0.0.0: build (lib + exe)
Preprocessing library for myproject-0.0.0..
Building library for myproject-0.0.0..
[1 of 2] Compiling Lib ( src/Lib.hs, .stack-work/dist/x86_64-linux-tinfo6/Cabal-2.2.0.1/build/Lib.o )
[2 of 2] Compiling Paths_myproject ( .stack-work/dist/x86_64-linux-tinfo6/Cabal-2.2.0.1/build/autogen/Paths_myproject.hs, .stack-work/dist/x86_64-linux-tinfo6/Cabal-2.2.0.1/build/Paths_myproject.o )
Preprocessing executable 'bar' for myproject-0.0.0..
Building executable 'bar' for myproject-0.0.0..
/home/luc/test/app/Baz.hs:1:8: error:
File name does not match module name:
Saw: ‘Main’
Expected: ‘Baz’
|
1 | module Main where
| ^^^^
-- While building package myproject-0.0.0 using:
/home/luc/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.4 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-2.2.0.1 build lib:myproject exe:bar exe:baz exe:foo --ghc-options " -ddump-hi -ddump-to-file -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
The only difference between my setup and the example that I found was the capital letters of the files in app/. And indeed, if I change them to lower case (in the filesystem and the package.yaml) it all builds correctly.
But why is that and where is that documented?
I think app should not be considered as a convention to be a folder of all final applications. In my projects I always split these to foo/Main.hs and bar/Main.hs for foo and bar targets. Hence
package.yaml should contain
executables:
foo:
main: Main.hs
source-dirs: foo
dependencies:
- myproject
bar:
main: Main.hs
source-dirs: bar
dependencies:
- myproject
And treat myproject just as a library for them

Resources