Haskell stack C++ 链接失败

5

我正在尝试编写一个Haskell库,并在stack ghci中收到错误消息:

ghci> functionThatCalls_cSmithNormalForm 0
ghc-9.4.5: ^^ Could not load 'csmith_normal_form', dependency unresolved. See top entry above.

GHC.ByteCode.Linker: can't find label
During interactive linking, GHCi couldn't find the following symbol:
  csmith_normal_form

每当我调用在SNF.hs中定义的函数 cSmithNormalForm 时:
foreign import ccall "csmith_normal_form" cSmithNormalForm :: Ptr CLLong -> IO (Ptr CLLong)

C++函数在snf.cpp文件中导出(整个项目中唯一的C++文件)如下:
using i64 = long long;
(...)
extern "C" {
    i64 *csmith_normal_form(i64[]);

    i64 *csmith_normal_form(i64 _mx[]) {
        (...)
    }
}

经过多次尝试创建此链接后,我的package.yaml文件包含以下内容:
cxx-sources:
- src/snf.cpp
cxx-options:
- -std=c++17

include-dirs:
- src

library:
  source-dirs: src
  cxx-sources:
  - src/snf.cpp
  cxx-options:
  - -std=c++17
  when:
    - condition: os(linux)
      extra-libraries: stdc++

stack.yaml文件保持不变。SNF.hs和snf.cpp都位于同一个目录(src)中。

尽管出现错误,但stack build运行成功。

有没有办法修复错误并成功地从Haskell调用C++函数?此外,是否有关于如何使用像cxx-options这样的选项的可用文档?我找不到任何官方的资料。

1个回答

3
这是一个 Stack 的错误。GHCi 需要在命令行中传递任何独立的外部 .o 文件作为参数。Stack 检查 Cabal 中的 c-sources 来确定适当的 C .o 文件列表,但它不检查 cxx-sources 行。
有几个可能的解决方法。
首先,你可以尝试自己传递正确的文件名,例如:
$ stack ghci --ghci-options $(find .stack-work -name 'snf.o')

第二,你可以考虑在行中指定你的C++源文件,而不是行。Stack和Cabal允许在中列出C和C++文件,并根据文件扩展名正确识别它们。首先使用字段的唯一原因是允许使用不同的和字段,以便使用不同的标志编译C和C++文件(请参阅cxx-sources文档)。

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