Haskell llvm-general JIT: calling a C function on the fly. Stephen Diehl Tutorial

I follow Stephen Dichl, an excellent LLVM Haskell tutorial , in the Linux Mint field (Linux Mint 17 Qiana, GHC 7.8.4, llvm 3.4).

I cloned a github repo project, and I was able to build each example chapter using the included Makefile .

In chapter 4, the tutorial introduces us to the JIT compiler:

 import qualified LLVM.General.ExecutionEngine as EE jit :: Context -> (EE.MCJIT -> IO a) -> IO a jit c = EE.withMCJIT c optlevel model ptrelim fastins where optlevel = Just 2 -- optimization level model = Nothing -- code model ( Default ) ptrelim = Nothing -- frame pointer elimination fastins = Nothing -- fast instruction selection runJIT :: AST.Module -> IO (Either String ()) runJIT mod = do ... jit context $ \executionEngine -> ... EE.withModuleInEngine executionEngine m $ \ee -> do mainfn <- EE.getFunction ee (AST.Name "main") case mainfn of Just fn -> do res <- run fn putStrLn $ "Evaluated to: " ++ show res Nothing -> return () 

Then the tutorial expands the language by writing C code to perform operations.

 /* cbits $ gcc -fPIC -shared cbits.c -o cbits.so $ clang -fPIC -shared cbits.c -o cbits.so */ #include "stdio.h" // putchard - putchar that takes a double and returns 0. double putchard(double X) { putchar((char)X); fflush(stdout); return 0; } 

The makefile creates the project by running:

 gcc -fPIC -shared src/chapter4/cbits.c -o src/chapter4/cbits.so ghc -no-user-package-db -package-db .cabal-sandbox/*-packages.conf.d src/chapter4/cbits.so --make src/chapter4/*.hs -o chapter4 

But when I try to call putchard() , I get an error message:

 LLVM ERROR: Program used external function 'putchard' which could not be resolved! 

Did I miss something?

I saw people having a similar problem with the original C ++ tutorial. They usually solve it by adding a flag to the gcc build ( -rdynamic ) -rdynamic , which should force the linker to add all the characters, not just the ones used, to the dynamic symbol table. I suspect ghc robs putchard() from the executable.

When I follow the same steps in OS X, everything works fine and I can call putchard() without any problems.

What's happening?

I just tried launching the project on Centos 7 and it worked. There must be something wrong with my Mint machine.

+5
source share
1 answer

Perhaps the GHC is a bit overdone while binding and deleting a character? You can manually add the link using FFI in Main.hs and then recompile.

 {-# LANGUAGE ForeignFunctionInterface #-} import Foreign.C.Types foreign import ccall safe "putchard" putchard :: CDouble -> CDouble 
+1
source

All Articles