我在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