I have a project with this structure:
foo.cabal
src/
Foo/
Main.hs
and part of foo.cabal looks like this:
executable foo
main-is: Foo/Main.hs
hs-source-dirs: src
Main.hs has the package name Foo.Main. When I build it cabal compiles everything but doesn't create an executable because it says there is no main module.
Warning: output was redirected with -o, but no output will be generated
because there is no Main module.
What am I doing wrong?
[EDIT] If I move Main up a level and change foo.cabal to read main-is: Main.hs it works. So can I not have a nested module name for Main?
The Main module must be called Main, not Foo.Main or anything else. If you want Foo.Main, then rename main in it to something like defaultMain, then make a top level Main module that imports Foo.Main (defaultMain) and defines main = defaultMain, such as:
src/
Foo/
Main.hs
Main.hs
foo.cabal
Where
-- src/Foo/Main.hs
module Foo.Main
( defaultMain
) where
defaultMain :: IO ()
defaultMain = putStrLn "Hello, world!"
And
-- src/Main.hs
module Main where
import Foo.Main (defaultMain)
main :: IO ()
main = defaultMain
Alternatively, you could keep it Foo.Main.main and just import it qualified.
Cabal's main-is: specifies only the filename from which to build the module containing the entrypoint (default Main.main); it does not allow changing that default.
Changing the default is compiler-specific, but if you are using GHC you can do this by passing a compiler command-line option: to your Cabal file executable definition add ghc-options: -main-is Foo. You may also use a different top-level function as the entry point: ghc-options: Foo.startup for example. See -main-is <thing> in the documentation for more details.
If you're using a package.yaml (as used by hpack/Stack/etc.) you may specify for main: either:
.hs filename, in which case that will be directly used on the main-is: line in the generated Cabal file; orFoo or Foo.startup) in which case the appropriate ghc-options: -main-is ... will be added to the generated Cabal file and main-is: will be a filename generated from the module name (e.g. main-is: Foo.hs).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With