无C main函数时,如何生成并链接含Haskell导出函数的.o文件
从C调用Haskell函数并生成可被其他程序链接的库文件
需求
我知道如何从C调用Haskell函数,但不想生成可执行文件,而是要创建能和其他.o文件链接的库文件(可被其他C程序调用)。
代码示例
Safe.hs
{-# LANGUAGE ForeignFunctionInterface #-} module Safe where 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 <HsFFI.h> #ifdef __GLASGOW_HASKELL__ #include "Safe_stub.h" #endif int foo() { int i; // 定义合法的argc和argv,避免未定义错误 int argc = 0; char *argv[] = {NULL}; hs_init(&argc, &argv); i = fibonacci_hs(42); hs_exit(); return i; }
已尝试的操作及错误
编译Haskell代码:
ghc -fPIE -c -O Safe.hs生成
Safe_stub.h、Safe.o和Safe.hi,这一步没问题。编译C代码:
ghc --make -fPIE -no-hs-main -optc-O -c test.c -o test.o得到
test.o。尝试链接生成目标文件:
ghc -no-hs-main -optc-nostartfiles -optc-static-pie test.o Safe.o -o result.o报错:
/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crt1.o:function _start: error: undefined reference to 'main' collect2: error: ld returned 1 exit status `x86_64-linux-gnu-gcc' failed in phase `Linker'. (Exit code: 1)
补充说明:有人建议用ld -r链接,但该方法无法引入Haskell运行时,我需要生成可被其他C程序调用的库文件。
问题分析与解决方案
错误原因
你试图用GHC生成单个.o文件,但GHC默认会尝试生成可执行文件——即使指定-o result.o,它依然会链接启动代码(比如crt1.o),而启动代码依赖main函数,因此报错。另外,原test.c中argc和argv未定义,也是潜在问题。
正确操作步骤
步骤1:修复C代码中的未定义变量
按照上面的test.c示例,添加argc和argv的合法定义。
步骤2:重新编译C代码
直接用gcc编译,指定Haskell头文件路径:
gcc -c -O -fPIE test.c -o test.o -I$(ghc --print-libdir)/include
步骤3:生成动态库(推荐)
用GHC生成动态库,它会自动处理Haskell运行时的所有依赖:
ghc -shared -fPIE -no-hs-main -o libfoo.so test.o Safe.o
生成的libfoo.so可以被其他C程序链接调用,比如:
gcc -o main main.c -L. -lfoo -Wl,-rpath=.
(假设main.c中调用了foo()函数)
步骤4:生成静态库
如果需要静态库,先用ar打包目标文件,链接其他C程序时需手动指定所有Haskell依赖:
# 打包静态库 ar cr libfoo.a test.o Safe.o # 链接其他程序时带上Haskell运行时依赖 gcc -o main main.c libfoo.a $(ghc --print-libdir)/libHSrts.a -L$(ghc --print-libdir) -lHSbase-4.16.4.0 -lHSinteger-gmp-1.0.3.0 -lgmp -lm
注意:静态库需要手动指定所有Haskell依赖,因此动态库更方便维护。
内容的提问来源于stack exchange,提问作者Abhiroop Sarkar
相关产品推荐
相关产品推荐

