设置:我有一个Haskell库HLib
,该库可以调用C / C ++后端CLib
以提高效率。后端很小,专门用于HLib
。的接口CLib
将仅被通过暴露HLib
; HLib
测试,HLib
基准测试和第三方库(取决于)HLib
将不会直接向发出FFI调用CLib
。从test / benchmark / 3rd party lib的角度来看,HLib
应该纯粹是Haskell。这意味着在,例如,小集团文件部分HLib
的测试中,应该有任何引用-lCLib
,libCLib
等等,只有build-depends
上HLib
,并且可执行文件不应该需要寻找一个动态CLib
库。我需要能够在其中构建和运行所有可执行文件HLib
和第三方库,以及cabal repl
为开发而运行。
最初,CLib
写于纯C.卡瓦尔具有用于这种情况下的支持,并且我可以集成CLib
到HLib
在精确地,通过使用上面描述的方式include-dirs
,c-sources
和includes
在小集团文件字段。
CLib
已经发展成为一个C ++库,我不知道该如何使Cabal轻松集成。相反,我求助于具有自定义build和Setup.hs的makefile,例如this。您可以在1,2中看到此方法的一个小示例。
在该示例中,我无法运行cabal repl
,HLib
因为“不支持加载档案”。这确实意味着我需要一个动态的C ++库,该库创建起来很简单(CLib
makefile中有一个注释行可以做到这一点)。但是,如果我制作了动态C ++库,则HLib
由于“没有这样的文件或目录libclib.so” ,该测试在运行时失败。这很糟糕(除了崩溃),因为测试可执行文件链接到了动态库,而这并不是我想要的。
具体而言,对于测试HLib
和SimpleLib
都应该通了,我应该能够运行cabal repl
在双方hlib
和simplelib
目录。
我尝试过的其他操作:这个答案,这个答案(我无法编译),这个和阅读文档(导致“重定位”错误)。
我目前正在使用GHC-7.10.3,尽管如果在8.0中明显更方便,那就很好。
[1]从大声笑/挑战中简化。
[2]下载并运行./sandbox-init
。这会生成HLib
(隐式生成CLib
和SimpleLib
,这是一个依赖于的Haskell库)HLib
。
一旦您知道一些技巧,在Haskell库中包含C或C ++库就很简单了。
尽管这篇文章看起来过于复杂,但我从本文中获得了核心。您可以将Cabal(当前为1.25)用于Simple
构建类型(即没有特殊设置Setup.hs
),makefile和诸如的外部工具c2hs
。
要包含来自纯C库的符号:
Include-dirs: relative/path/to/headers/
或Includes: relative/path/to/myheader.h
。C-sources: relative/path/to/csources/c1.c, relative/path/to/csources/c2.c, etc
。C ++还有一些额外的功能:
.cpp
文件添加到C-sources
cabal文件中的字段。.cpp
Haskell需要访问的文件中的所有函数上,添加extern "C"
以避免名称修饰。#ifdef __cplusplus ... #endif
(请参见nm的答案)。extra-libraries: stdc++
到cabal文件中,并使用g++
进行链接ghc-options: -pgmlg++
。.c(pp)
cabal repl
而已!您可以在此处看到与stack
和一起使用的完整示例cabal
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句