从C调用Haskell,出现"multiple definition of main"链接错误

4

我正在尝试学习如何接口Haskell和C。为此,我编写了Inc.hs,这是我可以想到的最简单的东西:

{-# LANGUAGE ForeignFunctionInterface #-}

module Inc where

import Foreign
import Foreign.C.Types

inc :: Int -> Int
inc = (+1)

foreign export ccall cinc :: CInt -> CInt
cinc :: CInt -> CInt
cinc = fromIntegral . inc . fromIntegral

然后编译它以生成Inc_stub.h

ghc -c Inc.hs

工作得很好。然后我编写了C文件,尽可能简单:

#include <stdio.h>
#include "Inc_stub.h"

int main(int argc, char *argv[]) {
    int a = 1;
    hs_init(&argc, &argv);

    a = cinc(a);

    hs_exit();
    if (a == 2) {
        puts("Worked!");
    }

    return 0;
}

尝试编译时,出现以下链接器错误提示:
ghc -no-hs-main inc.c Inc -o simplest
Linking simplest.exe ...
inc.o:inc.c:(.text+0x0): multiple definition of `main'
Inc.o:inc.c:(.text+0x0): first defined here
Inc.o:inc.c:(.text+0x31): undefined reference to `cinc'
c:/program files/haskell platform/7.10.2-a/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/bin/ld.exe: Inc.o: bad reloc address 0x0 in section `.pdata'
collect2: ld returned 1 exit status

所有内容都是在Windows 10 64位系统上使用GHC 7.10.2进行编译的。


这是关于 GHC 的一个 bug:https://ghc.haskell.org/trac/ghc/ticket/11201#comment:3 - Edward Z. Yang
2个回答

4
这仅是对正在发生的事情的解释,请查看@Hakala的答案以获取解决方案。
问题在于Windows文件名不区分大小写。
当您执行时。
$ ghc -no-hs-main inc.c Inc -o simplest

GHC 调用 GCC 编译 inc.c 生成目标文件 inc.o。但在 Windows 上,它还会覆盖由 ghc -c Inc.hs 生成的 Inc.o。因此,实际上相当于执行以下命令:

$ ghc -no-hs-main inc.c inc.o -o simplest

inc.o链接两次显然会导致“多重定义”错误。


4
我做了以下几步:
  1. 将inc.c重命名为inc_main.c,因为C对象文件inc.o可能与haskell对象冲突
  2. 运行ghc -c -no-hs-main Inc.hs -o Inc.o
  3. 通过gcc -O -Wall -I/usr/lib/ghc/include -c inc_main.c生成C对象文件
  4. 使用ghc -no-hs-main Inc.o inc_main.o -o simplest链接到可执行文件
请注意保留HTML标记且不编写解释。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接