虽然网上有一些教程展示了如何使用Haskell函数编译C程序,但每个教程都用ghc编译它们的C代码。在“真实世界”中,C代码文件将使用gcc编译。
我的目标是从Haskell代码创建.o文件,然后将它们链接到核心C程序。下面是一个基本的工作示例。
Fibonacci.hs:
{-# LANGUAGE ForeignFunctionInterface #-}
module Fibonacci where
import Foreign
import Foreign.C.Types
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt
test.c的:
#include "Fibonacci_stub.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
hs_init(&argc, &argv);
i = fibonacci_hs(42);
printf("Fibonacci: %d\n", i);
hs_exit();
return 0;
}
Makefile:
all: test
test: Fibonacci.o test.o
gcc -shared Fibonacci.o test.o -o test
test.o: test.c
gcc -c -I/usr/lib/ghc/include test.c
Fibonacci.o: Fibonacci.hs
ghc -c -O Fibonacci.hs
clean:
rm *.o *.hi test *_stub.h
https://dl.dropboxusercontent.com/u/14826353/fibonacci.tgz
运行make时,首先:ghc编译器将生成Fibonacci_stub.h和Fibonacci.o文件。第二:gcc编译器将从test.c文件生成test.o文件。最后,gcc编译器应链接.o文件并生成可执行文件。
而是提供了此错误:
/ usr / bin / ld:Fibonacci.o:重定位R_X86_64_PC32对未定义的符号`base_GHCziBase_plusInt_closure'在制作共享对象时不能使用;用-fPIC重新编译 / usr / bin / ld:最终链接失败:错误值
输出说使用-fPIC,我试图将它放在几个地方,但这些尝试在消除错误方面并不富有成效。
答案 0 :(得分:2)
我一直面临类似的问题,试图将ghc的.o放入共享库并意识到ghc只是忽略-fPIC而没有立即共享标记(所以你的建议是正确的)。有关详细讨论,请参阅此link。链接标记为«已解决»,但自2009年以来ghc命令行中没有任何实际更改。简而言之,该行为的原因在于ghc实现,并且只提出解决方案是从Haskell代码构建单独的共享库。