Haskell Stack + Cabal ignore 'main-is' option and fail to build app [duplicate] - haskell

This question already has answers here:
Cabal output is redirected but not generated
(3 answers)
Closed 6 years ago.
Q: How to adjust cabal(stack?) settings so that app/LogAnalysis.hs is treated as main log after all?
Here is how I got myself this error:
Created new project with stack new xyz
Renamed app/Main.hs to app/LogAnalysis.hs
Adjusted main-is option in xyz.cabal file
Problem is I either entered that data somehow incorrectly or cabal ignores that new value. Here is error I get:
Preprocessing executable 'WeekTwo-exe' for WeekTwo-0.1.0.0...
<no location info>: error:
output was redirected with -o, but no output will be generated
because there is no Main module.
Here is relevant entry in xyz.cabal
executable WeekTwo-exe
hs-source-dirs: app
main-is: LogAnalysis.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, WeekTwo
default-language: Haskell2010
And module in question is:
module LogAnalysis where
import Log
main :: IO ()
main = print (parseMessage "I 29 la la")
Versions:
Stack - Version 1.3.2
GHC - 7.15
Cabal - 1.24.0.0
PS if it's of any interest I'm doin 2nd week of Haskel course CIS 194.

Is it possible you changed module Main where to module LogAnalysis where? If you did, you would get exactly this error.
Main-is just says check for the Main module inside this file, but it must still be the Main module, not the LogAnalysis module. This makes it clear that the main function in this file should be run, rather than some main functions that might happen to exist in some other modules.

Related

Hardcode datadir path upon installing executable

Problem: I've got a command-line tool written in Haskell that reads a data file. Upon installing the program, I'd like for the program to be able to read that data file regardless of the directory I find myself in. That is, upon installing, the path that the program knows should be aligned with the path that the installer chooses.
Initial attempt: I was directed to the section 7.6. Accessing data files from package code in Cabal (the library) and learned that I can import getDataDir :: IO FilePath from Paths_myprog, as long as I add Paths_myprog to other-modules (although Hpack auto-includes this by default) and that after installing my program, I can run it with:
myprog_datadir=~/tmp ~/.local/bin/myprog
Then all I need to do is have the installer move the data file to this directory, since myprog dynamically accesses that path rather than some hardcoded value. But I don't want to have to specify myprog_datadir=~/tmp in my environment every time I run the program, I want it hardcoded into the binary! And it seems that setting myprog_datadir=~/tmp when building and installing doesn't set a compile-time default.
So: Is there a way I can hardcode this path upon installation?
(Preferrably, an answer that relates to Stack, but a cabal-install answer is also greatly appreciated.)
Files listed in data-files are already automatically installed in the right location so that Paths_pkg will find them. Here's a minimal example:
% cat Main.hs
import Paths_so_test
main :: IO ()
main = getDataDir >>= putStrLn
% cat so-test.cabal
cabal-version: >=1.10
name: so-test
version: 0.1.0.0
build-type: Simple
data-files: test
executable so-test
main-is: Main.hs
other-modules: Paths_so_test
autogen-modules: Paths_so_test
build-depends: base >=4.14 && <4.15
default-language: Haskell2010
% cat test
Hello, world!
% cabal install
Wrote tarball sdist to
/home/dmwit/projects/oneoff/tmp.dir/dist-newstyle/sdist/so-test-0.1.0.0.tar.gz
Resolving dependencies...
Up to date
Symlinking 'so-test'
% cat `so-test`/test
Hello, world!

How can I configure Cabal to build two executables?

I'm trying to build a Haskell project using Cabal. I have a file src/Main.hs which contains the module Main and a function main. That file runs the web interface of my app. And I have another file, src/CLI.hs which contains the module CLI and a function main. I can run it just fine with runhaskell CLI ..., but I can't seem to compile it using cabal.
The thing is, even if I specify CLI.hs as the main file (main-is: CLI.hs), it still compiles the project with the main from src/Main.hs, thereby giving me the web app instead of the CLI.
I want to be able to compile two executables, one which is the web app, and one which is the CLI, specifying the entry points of each as main in CLI.hs and main in Main.hs, respectively.
Here's the segment of the .cabal file I'm using at the moment:
executable color-word-analyzer-cli
main-is: CLI.hs
other-modules: AnnotateColors
, CategorizeColor
, ColorMaps
, FindColors
, PlotColors
, Types
, Main
build-depends: base
, lucid
...
, wai-middleware-static
hs-source-dirs: src/
default-language: Haskell2010
executable color-word-analyzer-web
main-is: Main.hs
other-modules: AnnotateColors
, CategorizeColor
, ColorMaps
, FindColors
, PlotColors
, Types
, CLI
build-depends: base
, lucid
...
, wai-middleware-static
hs-source-dirs: src/
default-language: Haskell2010
Which throws the error (among others):
Building executable 'color-word-analyzer-cli' for color-word-analyzer-0.1.0.0..
Warning: Enabling workaround for Main module 'Main' listed in 'other-modules'
illegally!
<no location info>: warning: [-Wmissing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules:
Main
which is funny, since Main is clearly listed there in other-modules.
I'm using cabal version 3.0.0.0, and ghc version 8.8.2.
The fully explicit form of a compilation unit is <package>:<category>:<ident> where in the case the packages is color-word-analyzer, category is exe and ident is the executables. So for your case you can call:
cabal build color-word-analyzer:exe:color-word-analyzer-cli color-word-analyzer:exe:color-word-analyzer-web
Now you don't actually need to specify all of that. When the executable is unique the fact that it is an executable (and not, say, a test from some other package or another package name itself) and the fact that it is from color-word-analyzer is clear in this context. You can therefore call:
cabal build color-word-analyzer-cli color-word-analyzer-web
EDIT: because your link didn't have a stanza for -web I used one of my own creation which didn't include the CLI module. Notice your CLI file is module Main so that explains the error you see - you can't include a module Main as a library module.

Why is `stack build` altering my .cabal file?

I am attempting to build a project which uses Euterpea.
Running stack build I get the following error, suggesting that I need to add Euterpea to the build-depends section of my .cabal file.
$ sb
composition-0.1.0.0: build (lib + exe)
Preprocessing library composition-0.1.0.0...
[2 of 2] Compiling Lib ( src/Lib.hs, .stack-work/dist/x86_64-linux-nix/Cabal-1.24.2.0/build/Lib.o )
/home/matthew/backup/composition/composition/src/Lib.hs:5:1: error:
Failed to load interface for ‘Euterpea’
It is a member of the hidden package ‘Euterpea-2.0.4’.
Perhaps you need to add ‘Euterpea’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
-- While building package composition-0.1.0.0 using:
/home/matthew/.stack/setup-exe-cache/x86_64-linux-nix/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-linux-nix/Cabal-1.24.2.0 build lib:composition exe:composition-exe --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1
I add Euterpea there, and the library section of my .cabal file then is the following.
library
hs-source-dirs:
src
build-depends: base >= 4.7 && < 5
, Euterpea
exposed-modules:
Lib
other-modules:
Paths_composition
default-language: Haskell2010
However, when I then run stack build again, it gives the same error -- and changes my .cabal file back to what it was originally, with the library section then looking like
library
hs-source-dirs:
src
build-depends:
base >= 4.7 && < 5
exposed-modules:
Lib
other-modules:
Paths_composition
default-language: Haskell2010
Why is stack build altering my cabal file? I have never seen that occurring before.
Side note:
Not sure if it is related, but the .cabal file's format appears to be different than it normally does. Here as with previous projects I auto-initialized by running stack new <project-name>. I don't know what I might have done different from previous projects to cause this unexpected behavior of stack build.
Make sure package.yaml exists in the root of your project directory.
package.yaml is a new file format to improve the syntax of cabal, converted by hpack.
Stack supports hpack as strongly as the stack build command automatically converts package.yaml into a cabal file with hpack command.
So, delete package.yaml or edit package.yaml to add Euterpea package.
Editing it would not be so difficult as its format is YAML.
I want to add to the YAMAMOTO Yuji's answer. The solution is absolutely right. But I just wanted to add few things, it is not hard to edit the package.yaml.
Step 1 : The trickiest part is finding the correct package name.
Use Hoogle or Stackage to find the package where the module
resides. Read more about how to find package name in this post.
Step 2 : Now you have to open the package.yaml file and add the package name. In your case add 'Euterpea' package in the list of dependencies.
dependencies:
...
- your-package-name
Please note that Euterpea package has to be added in a different way. Please read this
post for better understanding.
Step 3 : Open project-name.cabal in project root and add required package name under build-depends:
library
hs-source-dirs:
src
build-depends:
base >= 4.7 && < 5
, your-package-name
exposed-modules:
Lib
Step 4 :Issue stack build to download and build dependencies
(or stack ghci if you plan to use it in the REPL)
Hope this works! Happy coding! :)

stack is overwriting my .cabal file when i added a dependency and run 'stack build' [duplicate]

I am attempting to build a project which uses Euterpea.
Running stack build I get the following error, suggesting that I need to add Euterpea to the build-depends section of my .cabal file.
$ sb
composition-0.1.0.0: build (lib + exe)
Preprocessing library composition-0.1.0.0...
[2 of 2] Compiling Lib ( src/Lib.hs, .stack-work/dist/x86_64-linux-nix/Cabal-1.24.2.0/build/Lib.o )
/home/matthew/backup/composition/composition/src/Lib.hs:5:1: error:
Failed to load interface for ‘Euterpea’
It is a member of the hidden package ‘Euterpea-2.0.4’.
Perhaps you need to add ‘Euterpea’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
-- While building package composition-0.1.0.0 using:
/home/matthew/.stack/setup-exe-cache/x86_64-linux-nix/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-linux-nix/Cabal-1.24.2.0 build lib:composition exe:composition-exe --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1
I add Euterpea there, and the library section of my .cabal file then is the following.
library
hs-source-dirs:
src
build-depends: base >= 4.7 && < 5
, Euterpea
exposed-modules:
Lib
other-modules:
Paths_composition
default-language: Haskell2010
However, when I then run stack build again, it gives the same error -- and changes my .cabal file back to what it was originally, with the library section then looking like
library
hs-source-dirs:
src
build-depends:
base >= 4.7 && < 5
exposed-modules:
Lib
other-modules:
Paths_composition
default-language: Haskell2010
Why is stack build altering my cabal file? I have never seen that occurring before.
Side note:
Not sure if it is related, but the .cabal file's format appears to be different than it normally does. Here as with previous projects I auto-initialized by running stack new <project-name>. I don't know what I might have done different from previous projects to cause this unexpected behavior of stack build.
Make sure package.yaml exists in the root of your project directory.
package.yaml is a new file format to improve the syntax of cabal, converted by hpack.
Stack supports hpack as strongly as the stack build command automatically converts package.yaml into a cabal file with hpack command.
So, delete package.yaml or edit package.yaml to add Euterpea package.
Editing it would not be so difficult as its format is YAML.
I want to add to the YAMAMOTO Yuji's answer. The solution is absolutely right. But I just wanted to add few things, it is not hard to edit the package.yaml.
Step 1 : The trickiest part is finding the correct package name.
Use Hoogle or Stackage to find the package where the module
resides. Read more about how to find package name in this post.
Step 2 : Now you have to open the package.yaml file and add the package name. In your case add 'Euterpea' package in the list of dependencies.
dependencies:
...
- your-package-name
Please note that Euterpea package has to be added in a different way. Please read this
post for better understanding.
Step 3 : Open project-name.cabal in project root and add required package name under build-depends:
library
hs-source-dirs:
src
build-depends:
base >= 4.7 && < 5
, your-package-name
exposed-modules:
Lib
Step 4 :Issue stack build to download and build dependencies
(or stack ghci if you plan to use it in the REPL)
Hope this works! Happy coding! :)

How do I add the "containers" package to my .cabal file (without getting overwritten by stack at compile time)?

I am working on the "roman-numerals" task from the exercism Haskell track and followed their instructions to installing stack. I am working on a Fedora 24 box.
As long as I was working with Haskell modules from base, I didn't have a problem. Now I am trying to import the Data.Map module. It works fine using the ghci command line:
$ ghci
GHCi, version 7.8.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> import Data.Map
Prelude Data.Map>
However, when I try to import it from inside my src file with the command:
import qualified Data.Map as M (foldlWithKey, fromList)
I am running into problems when I try to run the test:
$ stack test
roman-numerals-0.0.0: build (lib + test)
Preprocessing library roman-numerals-0.0.0...
[2 of 2] Compiling Roman (...)
(...) /roman-numerals/src/Roman.hs:3:1: error:
Failed to load interface for ‘Data.Map’
It is a member of the hidden package ‘containers-0.5.7.1’.
Perhaps you need to add ‘containers’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
Progress: 1/2
(...)
I googled the problem and found a straightforward solution at the Cabal FAQ at haskell.org:
What you need to do is to add containers to the build-depends in your .cabal file.
I am assuming they mean the file roman-numerals.cabal that is in my working directory. The contents are:
-- This file has been generated from package.yaml by hpack version 0.14.0.
--
-- see: https://github.com/sol/hpack
name: roman-numerals
version: 0.0.0
build-type: Simple
cabal-version: >= 1.10
library
hs-source-dirs:
src
build-depends:
base
exposed-modules:
Roman
other-modules:
Paths_roman_numerals
default-language: Haskell2010
test-suite test
type: exitcode-stdio-1.0
main-is: Tests.hs
hs-source-dirs:
test
build-depends:
base
, roman-numerals
, hspec
default-language: Haskell2010
I tried to add "containers" to the build-depends in either and both the "library" and "test-suite" sections, but when I run
$ stack test
the error persists, and the .cabal file is reverted to the same contents shown above.
Any pointers? Much appreciated!
This is hinting at the problem:
-- This file has been generated from package.yaml by hpack version 0.14.0.
--
-- see: https://github.com/sol/hpack
hpack is an alternative, YAML-based specification format for Haskell packages which can be used instead of the traditional cabal format. The hpack program can then be used to convert a specification from the hpack format to the cabal format to be able to integrate with the rest of the Haskell toolchain.
Some basic support for hpack was added to stack some time ago. It checks for a file called package.yaml in the current directory, which is the standard name for hpack format package specifications, and if it exists, it runs hpack to convert it to a cabal file and then proceeds building as normal. This is what's trampling over your .cabal file.
To solve this, either:
Modify package.yaml instead of roman-numerals.cabal to achieve the same effect.
Delete package.yaml and continue working directly with roman-numerals.cabal.
The syntax for adding dependencies in the hpack format is:
dependencies:
- base
- containers

Resources