2013-12-12 170 views
0

雖然網上有幾個教程展示瞭如何使用Haskell函數編譯C程序,但每個教程都使用ghc編譯它們的C代碼。在「真實世界」中,將使用gcc編譯C代碼文件。如何將Haskell代碼集成到C程序中?

我的目標是從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 /斌/ LD:Fibonacci.o:針對未定義的符號`base_GHCziBase_plusInt_closure」重定位R_X86_64_PC32不能創建共享對象時使用;與-fPIC 的/ usr/bin中/ LD編譯:最後一個環節失敗:錯誤值

輸出表示使用-fPIC,我試圖把它在幾個地方,但這些嘗試都沒有取得豐碩成果在消除錯誤。

  1. 我應該在Makefile中放置-fPIC?
  2. -fPIC建議有用嗎? Makefile中存在明顯的缺陷,它會阻止編譯?

回答

1

我一直在面對類似的問題,試圖把ghc的.o放到共享庫中,並意識到ghc只是忽略-fPIC而沒有立即共享標誌(所以你的建議是正確的)。有關詳細的討論,請參閱此link。該鏈接的標記爲「已解決」,但自2009年以來ghc命令行中沒有任何實際變化。簡單地說,該行爲的原因在於ghc實現,並且唯一提出的解決方案是從Haskell代碼構建單獨的共享庫。

+0

或者,由於OP似乎不需要共享對象,因此他可能會嘗試從'gcc -shared Fibonacci.o test.o -o test'中刪除'-shared'。 – Armali

相關問題