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