Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


executables with a C main function #497

bos opened this Issue · 5 comments

4 participants


(Imported from Trac #504, reported by @dcoutts on 2009-02-22)

We would like to be able to do:

executable blah
main-is: main.c
Either for pure C programs or mixed C/Haskell programs with main in the C code rather than Haskell code.


Until this is implemented one can use a main in Haskell that calls out to the C main function. For example:


int real_main () {
return 42;

import System.Exit
import Foreign.C
main = real_main >>= exitWith . ExitFailure . fromIntegral
foreign import ccall "real_main" real_main :: IO CInt

name: c-main
version: 0.0
build-type: Simple
cabal-version: >= 1.2
extra-source-files: main.h
executable c-main
main-is: Main.hs
c-sources: main.c
includes: main.h
extensions: ForeignFunctionInterface
build-depends: base

Implementation notes

At the moment Cabal's "Simple" build system requires main-is to specify a .hs or .lhs file (though it does allow that to be generated by a pre-processor). If we lift that restriction the first thing to go wrong will be that ghc --make does not work with -no-hs-main. We will have to do the build and link steps separately (which is probably a good thing anyway). We would use ghc --make to compile all Haskell modules to .o files and then invoke ghc in batch mode passing it all the .o files (from Haskell and C modules) and -package flags. If we're using a C main then we'd do the link step with -no-hs-main.

@ghost ghost was assigned

(Imported comment by jcpetruzza on 2009-02-22)

I believe the lack of this feature makes SDL-based applications currently unbuildable on OS X.

On OS X, SDL.h "renames" (using a macro) the "main" function to "_SDL_main"; the latter is then called from a "main" function defined in libSDLmain.a (with which every SDL-based program has to be linked). For this to work with Haskell, the workaround suggested in the SDL package is to use a C wrapper which includes SDL.h and defines a "main" function that calls, via the FFI, the entry-point of the haskell application.

Notice that the workaround suggested in the ticket description does not work in this case, since the "main" function defined in the haskell wrapper would collide with the one in libSDLmain.a when linked.

Observe also, that for this feature to work in a mixed Haskell/C setting like the one described, the .c program cannot be compiled first (as I think is the case with declared c-files), since it will need to #include the stubs generated from processing FFI export declarations.


(Imported comment by @dankna on 2011-04-18)

I have submitted a patch for this with darcs send. My patch simply relaxes the restriction on the name of the file given to main-is: to also allow known C-language extensions. The ticket description suggested that -no-hs-main might be required in this situation, but that seems to no longer be the case. There might still be a problem when the entry point is WinMain?() instead of main(); see GHC ticket #2459 (at ). I'm not really set up to test that case.


Adapted dankna's patchset to Git. Modern GHC does need -no-hs-main.



IIUC, this is fixed. OK to close this ticket?


Appears to be resolved.

@ttuegel ttuegel closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.