[Haskell-cafe] greencard and cabal, how to do it right?

Marc Weber marco-oweber at gmx.de
Sun Dec 17 15:29:02 EST 2006

I want to have a look at fruit which is using GCJNI, greencard, ...
That's why I want to learn how to use greencard with cabal.

If this is only a RTFM problem, can you point me to the docs?

When using the cabal builtin preprocessor I get the error that
--libdir has to be specified.

So I tried adding this manually using a custom proprocessor beeing
copied mostly from the already existing one:

-- setup.hs -----------------------------------------------------------

	import Distribution.PackageDescription
	import Distribution.Simple.Utils (rawSystemVerbose, dieWithLocation)

	main= do
	  defaultMainWithHooks $ defaultUserHooks { hookedPreProcessors = [ myGreencardPP ] }
	  where myGreencardPP :: (String, BuildInfo -> LocalBuildInfo -> PreProcessor)
		myGreencardPP = ("gc", ppGreenCard' ["--libdir ../c_lib"] []) -- << --libdir is added here

	-- copied from Distribution.PreProcess
	ppGreenCard' :: [String] -> [String] -> BuildInfo -> LocalBuildInfo -> PreProcessor
	ppGreenCard' args inputArgs bi lbi
	    = maybe (ppNone "greencard") pp (withGreencard lbi)
	    where pp greencard inFile outFile verbose
		      = rawSystemVerbose verbose greencard (args ++ ["-tffi", "-o" ++ outFile, inFile] ++ inputArgs)
	ppNone :: String -> PreProcessor
	ppNone name inFile _ _ =
	    dieWithLocation inFile Nothing $ "no " ++ name ++ " preprocessor available"


I don't understand why the command does work but not when beeing executed by cabal:

The commandline shows the directory content (no Greencard.hs). (1>)

Then it executes ./setup -v build which shows the commandline failing (2>)

Then it executes this commandline from shell 
(using bash eval and getting the greencard line by grepping the output from ./setup -v build)
The final ls (3>) shows that Greencard.hs is there.
I've marked these parts using > and * *
I've also replaced the greencard executable by a shell script printing pwd which is the same..
Whats going wrong here? How to do it right?

>       $ ls; ./setup -v build || echo -e "\n\n ===> build failed \n\n"; eval `./setup -v build 2>&1 | grep /usr/local/bin/greencard` && echo -e "\n\n =====> this works why?" ; ls
1>      Greencard.cabal  Greencard.gc  Greencard_stub_ffi.c  Greencard_stub_ffi.h  dist  greencard_stub_ffi.c  greencard_stub_ffi.h  setup  setup.hi  setup.hs
        Preprocessing executables for greencard-0.0...
2>      */usr/local/bin/greencard --libdir ../c_lib -tffi -oGreencard.hs Greencard.gc*
        unrecognized option `--libdir ../c_lib'
        Usage: greencard [OPTION]... SOURCE

        Run Green Card, a foreign function interface preprocessor
        for Haskell, over SOURCE

        Green Card home page:

          -?, -h     --help                         print out this help message and exit
          -V         --version                      output version information and exit
          -v         --verbose                      print more information
          -d         --debug                        output extra debug information
                     --print-libdir                 output default library location
                     --libdir=DIR                   use base library location
          -i DIRS    --include-dir=DIRS             Add DIRS (colon separated) to the include search path
          -s SUFS    --suffix=SUFS                  colon separated list of source file suffixes
          -t TARGET  --target=TARGET                generate Haskell code for a particular system (ghc, ffi)
          -S         --safe-code                    call C `safely' (GHC only)
          -n         --no-inline                    put C code in a separate file (GHC only)
          -4         --haskell1.4                   generate code compatible with a Haskell 1.4 system
          -m SCHEME  --name-mangling-scheme=SCHEME  controls mapping of external names into Haskell ones (std, classic)
          -D         --stub-debug                   include debugging code in generated code
          -f DLL     --dllname=DLL                  generate 'foreign imports' to dynamic library DLL (FFI backend only)
          -C CCONV   --callconv=CCONV               use specific calling convention (stdcall, ccall)
          -o FILE    --output=FILE                  write Green Card Haskell output to FILE
          -c FILE    --output-c=FILE                write Green Card C output to FILE
          -p PRE     --output-prefix=PRE            write Green Card Haskell output to PRE.{hs,c}

        Building greencard-0.0...
        /usr/bin/ghc -Idist/build -o dist/build/greencard/greencard --make -hide-all-packages -i -idist/build/autogen -i. -odir dist/build/greencard/greencard-tmp -hidir dist/build/greencard/greencard-tmp -package haskell98-1.0 -package base-2.0 -package QuickCheck-1.0 Greencard.gc -lc_lib -L../c_lib/
        ghc-6.5.20060917: no input files
        Usage: For basic information, try the `--help' option.

         ===> build failed

         =====> this works why?
3>       Greencard.cabal  Greencard.gc  *Greencard.hs*  Greencard_stub_ffi.c  Greencard_stub_ffi.h  dist  greencard_stub_ffi.c  greencard_stub_ffi.h  setup  setup.hi  setup.hs


More information about the Haskell-Cafe mailing list