Compile only one target from a stack project with multiple targets in the cabal file - haskell

I have a similar setup like this SO question.
However I'm working with stack and not directoly with cabal:
stack.yaml
Test.cabal
src/FirstExe
src/SecondExe
The stack file is minimal
resolver: lts-8.17
packages:
- '.'
The file Test.cabal has 2 executables:
name: Test
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.8
executable FirstExe
hs-source-dirs: src
main-is: FirstExe.hs
build-depends: base >=4.8 && <4.10
executable SecondExe
hs-source-dirs: src
main-is: SecondExe.hs
build-depends: base >=4.8 && <4.10
The src/FirstExe.hs compiles successfully:
main :: IO ()
main = putStrLn "FirstExe compiles nicely"
The src/SecondExe.hs has an error:
main :: IO ()
main = "SecondExe gives compiler error" -- putStrLn is missing ...
(Note: The goal of this error is to see, when stack builds the SecondExe.)
When I do a stack ide targets I get
Test:exe:FirstExe
Test:exe:SecondExe
Now I want to compile only the first target FirstExe without compiling the second and without changing
the Test.cabal file. In reallity I will switch between the 2 executables.
According to the Haskell Tool Stack documentation it should
be possible
I tried two possibilies:
stack build :FirstExe
stack build Test:exe:FirstExe
In both cases it compiles the second executable too!
Test-0.1.0.0: configure (exe)
Configuring Test-0.1.0.0...
Test-0.1.0.0: build (exe)
Preprocessing executable 'FirstExe' for Test-0.1.0.0...
Preprocessing executable 'SecondExe' for Test-0.1.0.0...
[1 of 1] Compiling Main ( src/SecondExe.hs, .stack-work/dist/x86_64-linux-nopie/Cabal-1.24.2.0/build/SecondExe/SecondExe-tmp/Main.o )
/home/roland/Projekte/HaskellTutorials/Test/src/SecondExe.hs:2:8: error:
* Couldn't match expected type `IO ()' with actual type `[Char]'
* In the expression: "SecondExe gives compiler error"
In an equation for `main': main = "SecondExe gives compiler error"
-- While building package Test-0.1.0.0 using:
/home/roland/.stack/setup-exe-cache/x86_64-linux-nopie/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-linux-nopie/Cabal-1.24.2.0 build exe:FirstExe exe:SecondExe --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1
What am I doing wrong?

Related

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

Haskell Failed to load interface for module

Hello i am trying to use a module inside another module but it seems it just won't work.I tried updating the cabal file,stack,i reinstalled the platform,ghc and everything and it just won't let it import modules.I tried adding in the cabal file both other-modules and home-modules section ..to no effect.What could be the problem?
Modules:
module Test where
test::IO()
test=do
elem<-getLine
print elem
module Main where
import Test
main :: IO ()
main = do
putStrLn "hello world"
Cabal-build renders this error:
$ cabal build
Resolving dependencies...
Configuring console-0.1.0.0...
Warning: To use the 'default-language' field the package needs to specify at
least 'cabal-version: >= 1.10'.
Preprocessing executable 'console' for console-0.1.0.0..
Building executable 'console' for console-0.1.0.0..
<no location info>: warning: [-Wmissing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules: Test
<no location info>: warning: [-Wmissing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules: Test
When i build with Stack i get this error:
C:\<path>\Main.hs:4:1: error:
Failed to load interface for `Test'
Use -v to see a list of the files searched for.
Failed, modules loaded: none.
H>>= :module + *Main
Cabal file:
name: console
version: 0.1.0.0
-- synopsis:
-- description:
homepage: https://github.com/githubuser/console#readme
license: BSD3
license-file: LICENSE
author: Bercovici Adrian Simon
maintainer: example#example.com
copyright: 2018 Bercovici Adrian Simon
category: Web
build-type: Simple
cabal-version: >=1.2
extra-source-files: README.md
Executable console
hs-source-dirs: src
main-is: Main.hs
default-language: Haskell2010
build-depends: base >= 4.7 && < 5
other-modules: Test
The other-modules: directive must go inside the Executable console stanza.

Could not find module ‘Test.HUnit’

I have a fresh installation of stack and ghci:
$ stack --version
Version 1.6.3, Git revision b27e629b8c4ce369e3b8273f04db193b060000db (5454 commits) x86_64 hpack-0.20.0
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.2.1
I make a new project:
$ stack new so-mve
Downloading template "new-template" to create project "so-mve" in so-mve/
... blah blah blah ...
Looking for .cabal or package.yaml files to use to init the project.
Using cabal packages:
- so-mve/
Selecting the best among 12 snapshots...
* Matches lts-10.3
Selected resolver: lts-10.3
Initialising configuration using resolver: lts-10.3
Total number of user packages considered: 1
Writing configuration to file: so-mve/stack.yaml
All done.
Looks pretty good:
$ tree so-mve
so-mve
├── ChangeLog.md
├── LICENSE
├── README.md
├── Setup.hs
├── app
│   └── Main.hs
├── package.yaml
├── so-mve.cabal
├── src
│   └── Lib.hs
├── stack.yaml
└── test
└── Spec.hs
It builds and runs:
$ cd so-mve
$ stack build
so-mve-0.1.0.0: build (lib + exe)
Preprocessing library for so-mve-0.1.0.0..
Building library for so-mve-0.1.0.0..
Preprocessing executable 'so-mve-exe' for so-mve-0.1.0.0..
Building executable 'so-mve-exe' for so-mve-0.1.0.0..
so-mve-0.1.0.0: copy/register
Installing library in /...blah-blah.../so-mve/.stack-work/install/x86_64-osx/lts-10.3/8.2.2/lib/x86_64-osx-ghc-8.2.2/so-mve-0.1.0.0-5kG2WnHWwo99IiYYGoxrcC
Installing executable so-mve-exe in /...blah-blah.../so-mve/.stack-work/install/x86_64-osx/lts-10.3/8.2.2/bin
Registering library for so-mve-0.1.0.0..
$ stack exec so-mve-exe
someFunc
Tests run:
$ stack test
blah blah blah
[2 of 2] Compiling Main ( test/Spec.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/so-mve-test/so-mve-test-tmp/Main.o )
...blah-blah-blah...
Progress: 1/2Test suite not yet implemented
so-mve-0.1.0.0: Test suite so-mve-test passed
Completed 2 action(s).
I triple check that HUnit is installed
$ stack install HUnit
Populated index cache.
I add one line to test/Spec.hs
$ cat test/Spec.hs
import Test.HUnit
main :: IO ()
main = putStrLn "Test suite not yet implemented"
Doesn't work:
$ stack test
so-mve-0.1.0.0: unregistering (components added: test:so-mve-test)
so-mve-0.1.0.0: build (lib + exe + test)
Preprocessing library for so-mve-0.1.0.0..
Building library for so-mve-0.1.0.0..
Preprocessing executable 'so-mve-exe' for so-mve-0.1.0.0..
Building executable 'so-mve-exe' for so-mve-0.1.0.0..
Preprocessing test suite 'so-mve-test' for so-mve-0.1.0.0..
Building test suite 'so-mve-test' for so-mve-0.1.0.0..
[2 of 2] Compiling Main ( test/Spec.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/so-mve-test/so-mve-test-tmp/Main.o )
/...blah-blah.../so-mve/test/Spec.hs:1:1: error:
Could not find module ‘Test.HUnit’
Use -v to see a list of the files searched for.
|
1 | import Test.HUnit
| ^^^^^^^^^^^^^^^^^
Progress: 1/2
-- While building custom Setup.hs for package so-mve-0.1.0.0 using:
/Users/XXXXXXXX/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_2.0.1.0_ghc-8.2.2 --builddir=.stack-work/dist/x86_64-osx/Cabal-2.0.1.0 build lib:so-mve exe:so-mve-exe test:so-mve-test --ghc-options " -ddump-hi -ddump-to-file -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
I don't have trouble importing other libraries, like Text.Read and Text.Printf.
I googled around a bunch, but didn't find an answer. Any ideas for me?
You just need to add HUnit to the dependencies for your test project. When using stack, you should edit the package.yaml file to specify dependencies. In particular, your test configuration should look something like:
tests:
so-mve-test:
main: Spec.hs
source-dirs: test
ghc-options:
- ...
dependencies:
- HUnit
This is documented in the latest Stack Guide, under the section Adding Dependencies.
You installed HUnit globally with stack, but that doesn't mean it is specified for your project.
Your cabal file for the project needs to specify a dependency on HUnit:
--so-mve.cabal
...
test-suite so-mve
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: base
, HUnit
...
Text.Read and Text.Printf are both included in base, so you don't need to specify an additional dependency.
As pointed out in the comments, since you're using a package.yaml (as opposed to a stack.yaml) configuration with the newer version of stack, you'll need to specify the dependency there instead of the .cabal file:
tests:
so-mve-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
dependencies:
- HUnit

Haskell stack fails with error message "unsatisfied constraints"

When building my project, I'm receiving a cryptic error
C:\Users\T60\Dropbox\note-build>stack build
note-build-0.1.0.0: build
Preprocessing library note-build-0.1.0.0...
setup-Simple-Cabal-1.22.5.0-ghc-7.10.3.exe: unsatisfied constraints
-- While building package note-build-0.1.0.0 using:
C:\stack_root\setup-exe-cache\i386-windows\setup-Simple-Cabal-1.22.5.0-ghc-7.10.3.exe --builddir=.stack-work\dist\95439361 build lib:note-build exe:note-build --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1
It seems to be caused by adding filepath to the executable depends section of my cabal file. My Main.hs file uses System.FilePath, and without the line in my cabal file it fails, but adding it gives me this error. Prior to trying to use the filepath module, the project would build.
executable note-build
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, filepath
, directory
, note-build
default-language: Haskell2010
What does this error mean, and am I putting the dependency in the wrong place in my cabal file?
Update: I ran the build using the -v flag, and it revealed that I'd absentmindedly substituted + for ++.
C:\Users\T60\Dropbox\note-build\app\Main.hs:20:31: #(stack_9kewhubnl5WIl89fhd1ea2:Stack.Build.Execute src/Stack\Build\Execute.hs:911:67)
2016-07-07 22:08:24.020516: [warn] No instance for (Num FilePath) arising from a use of `+' #(stack_9kewhubnl5WIl89fhd1ea2:Stack.Build.Execute src/Stack\Build\Execute.hs:911:67)
2016-07-07 22:08:24.051760: [warn] In the first argument of `normalise', namely `(y + "/")' #(stack_9kewhubnl5WIl89fhd1ea2:Stack.Build.Execute src/Stack\Build\Execute.hs:911:67)
2016-07-07 22:08:24.067386: [warn] In the expression: normalise (y + "/") #(stack_9kewhubnl5WIl89fhd1ea2:Stack.Build.Execute src/Stack\Build\Execute.hs:911:67)
2016-07-07 22:08:24.129886: [warn] In an equation for `y_norm': y_norm = normalise (y + "/").
So the fix was easy enough, but should I consider this a potential issue with stack that I had to use verbose output to see what seems like a simple type error?

Haskell stack not building test executable

Background
I'm building a logfile parser in Haskell. I'm using stack to build it. Running the stack build command works happily and my project compiles. Running stack test, however, produces the following error:
parser-test: executable not found
I see the the following warning above the error message but I don't know how to avoid the redirect to which it refers.
Warning: output was redirected with -o, but no output will be generated because there is no Main module.
Relevant files
I haven't written any tests yet so the test file is as it was created by stack new. My cabal file looks like this:
...
category: Executable
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
library
hs-source-dirs: src
exposed-modules: LogParser
build-depends: base >= 4.7 && < 5
, attoparsec
, bytestring
, old-locale
, time
default-language: Haskell2010
executable parser-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, attoparsec
, bytestring
, old-locale
, time
, parser
default-language: Haskell2010
test-suite parser-test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: base
, attoparsec
, bytestring
, hspec
, hspec-attoparsec
, old-locale
, time
, parser
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010
source-repository head
type: git
...
I presume I'm missing something but I can't find where what I'm missing is documented.
Desired behaviour
I should see the Test suite not yet implemented message outlined in the stack documentation.
The content of the test/Spec.hs file from the template is:
main :: IO ()
main = putStrLn "Test suite not yet implemented"
You can see this content at commercialhaskell/stack-templates in new-template.hsfiles.
I'm not sure where the module ParserSpec where line comes from (as brought up in the Github issue), but it's not part of the template. On my system, stack new bar && cd bar && stack test succeeds.
As to the reason behind the Main module requirement: it comes from the Cabal library, and as I understand it was added due to limitations in other compilers Cabal supports. In other words, GHC could technically allow this code to compile, but Cabal does not pass in those arguments to remain compatible with other compilers.

Resources