我在Linux Mint框(Linux Mint 17 Qiana,GHC 7.8.4,llvm 3.4)上关注Stephen Diehl's excellent LLVM Haskell tutorial。Haskell llvm-general JIT:即时调用C函数。 Stephen Diehl的教程
我克隆了项目的github回购,并且能够通过使用包含的Makefile
构建每章的示例。
在第4章教程呈现给我们一个JIT编译器:
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()
然后教程扩展了编写C代码来实现操作的语言。
/* 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;
}
生成文件通过运行生成项目:
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
但是,当我尝试调用putchard()
我得到一个错误:
LLVM ERROR: Program used external function 'putchard' which could not be resolved!
我失去了一些东西在这里?
我见过有人遇到与本教程的原始C++版本类似的问题。他们通常通过向gcc build命令(-rdynamic
)添加一个标志来解决这个问题,该命令可以使链接器将所有符号(不仅是已使用的符号)添加到动态符号表中。我怀疑ghc是从可执行文件中剥离putchard()
。
当我按照完全相同的步骤在OS X上,我一切正常,我可以打电话putchard()
没有问题。
发生了什么事?
我刚刚尝试在Centos 7上运行该项目,它工作。我的造币机器肯定有问题。
是否将''-optl -rdynamic''添加到ghc的调用中修复了问题?你可以运行'nm chapter4 | grep putchard''并将结果输出粘贴到问题中? – 2015-04-06 22:39:01
斯蒂芬,我曾尝试添加'-optl -rdynamic',但它没有工作。不幸的是,输出到'nm chapter4 | grep putchard'为null。看起来ghc忽略了'cbits.so'。在OS X上,如果可执行文件没有找到'cbits.so',它甚至不会运行。在Linux上它没有什么区别。也许有一种方法可以链接到ld而不是ghc?写这篇教程时你的设置是什么? – esato1981 2015-04-07 04:34:33
我已经测试了Ubuntu和Arch Linux上的代码。尽管如此,人们已经报告说它在每个主要操作系统上运行它。也许GHC上游存在一个链接器错误,在剥离不出现在Haskell源代码中的符号时有些过分热情。你在7.6或7.10上试过了吗? – 2015-04-08 23:32:12