问题
I'm trying to use Haskell's LLVM bindings to create a very simple 'hello world' standalone app. The idea is, when I run my Haskell application, it will spit out some bytecode that can in turn be run and will output "hello world!"
-- hellofunc prints out "hello world"
hellofunc :: CodeGenModule (Function (IO ()))
_main :: (Function (IO ())) -> CodeGenModule (Function (IO ()))
_main func = createNamedFunction ExternalLinkage "main" $ do
call func
ret ()
main = writeCodeGenModule "hello.bc" (liftA _main hellofunc)
When I run this, I see the following error:
'main' function not found in module.
I'm explicitly creating the main function using createNamedFunction. What am I missing?
回答1:
The problem lies in the use of liftA or fmap rather than =<<. It becomes more obvious (a build break) when type signatures are used. _main is not evaluated in CodeGenModule in the liftA case, and so it doesn't appear in the output file.
It may be reasonable to modify writeCodeGenModule to take CodeGenModule () instead of CodeGenModule a. It makes life just a bit more complicated for users of the LLVM JIT but would help prevent errors such as this one.
import Control.Applicative
import LLVM.Core
import LLVM.ExecutionEngine
import LLVM.Util.File
--
-- hellofunc prints out "hello world"
hellofunc :: CodeGenModule (Function (IO ()))
hellofunc = createNamedFunction ExternalLinkage "hello" $ do
ret ()
_main :: (Function (IO ())) -> CodeGenModule (Function (IO ()))
_main func = createNamedFunction ExternalLinkage "main" $ do
call func
ret ()
generateModuleBind :: CodeGenModule (Function (IO ()))
generateModuleBind = _main =<< hellofunc
-- Couldn't match expected type `Function (IO ())'
-- with actual type `CodeGenModule (Function (IO ()))'
--
-- this is the desired type:
-- generateModuleLiftA :: CodeGenModule (Function (IO ()))
--
-- but this is the actual type:
generateModuleLiftA :: CodeGenModule (CodeGenModule (Function (IO ())))
generateModuleLiftA = liftA _main hellofunc
main :: IO ()
main = writeCodeGenModule "hello.bc" generateModuleBind
来源:https://stackoverflow.com/questions/9427535/main-function-not-found-in-module-when-using-llvm-bindings-with-haskell