静态链接C++;具有Haskell库的库
设置:我有一个Haskell库静态链接C++;具有Haskell库的库,haskell,ghc,cabal,Haskell,Ghc,Cabal,设置:我有一个Haskell库HLib,它调用C/C++后端CLib,以提高效率。后端很小,专门用于HLib。到CLib的接口将仅通过HLib公开HLib测试、HLib基准测试和依赖于HLib的第三方库不会直接调用CLib。从测试/基准测试/第三方库的角度来看,HLib应该是纯粹的Haskell。这意味着在阴谋文件部分,例如,HLib测试,不应该有对-lCLib,libCLib等的引用,只有构建依赖于HLib,可执行文件不应该需要寻找动态CLib库。我需要能够在HLib和第三方libs中构建和运
HLib
,它调用C/C++后端CLib
,以提高效率。后端很小,专门用于HLib
。到CLib
的接口将仅通过HLib
公开HLib
测试、HLib
基准测试和依赖于HLib
的第三方库不会直接调用CLib
。从测试/基准测试/第三方库的角度来看,HLib
应该是纯粹的Haskell。这意味着在阴谋文件部分,例如,HLib
测试,不应该有对-lCLib
,libCLib
等的引用,只有构建依赖于HLib
,可执行文件不应该需要寻找动态CLib
库。我需要能够在HLib
和第三方libs中构建和运行所有可执行文件,以及运行cabal repl
进行开发
最初,CLib
是用纯C编写的。Cabal支持这个案例,我可以通过使用include dirs
,C-sources
,以及包含Cabal文件中的字段,以上述方式将CLib
集成到HLib
<代码> CLib <代码>已经演变成C++库,我无法理解如何使阴谋集团容易集成。相反,我使用了一个带有自定义build和Setup.hs的makefile,如。您可以看到此方法的一个小示例1,2
在该示例中,我无法在HLib
中运行cabal repl
,因为“不支持加载存档”。这意味着我需要一个动态C++库,它足够简单,可以创建(在<代码> CLib < /COD> MaFoE文件中有注释行来完成它)。但是,如果我真的做了动态C++库,那么<代码> HLib <代码>的测试在运行时失败,因为“没有这样的文件或目录LIclicli.SO”。这是不好的(除了崩溃),因为测试可执行文件链接到动态库,这不是我想要的
具体来说,HLib
和SimpleLib
的测试都应该通过,我应该能够在HLib
和SimpleLib
目录中运行cabal repl
我尝试过的其他事情:,(我无法编译)和读取(导致“重新定位”错误)
目前我正在使用GHC-7.10.3,不过如果在8.0中这要容易得多,那也没关系
[1] 简化自
[2] 下载并运行/sandboxinit
。这将构建HLib
(隐含地构造了< CLib > <代码> >代码> SimpleLib <代码>,这是一个依赖于代码> HLib < /C>的Haskell库。 GHC不能真正理解C++头文件。它需要纯C代码。C++头文件提供C接口的常用方法是将C++部分与<代码> > IFIFF和CPLUS PLUS < /代码>隔离,例如:
#ifdef __cplusplus
extern "C" { // C compilers and various C-based FFIs don't like this
#endif
void foo();
#ifdef __cplusplus
}
#endif
<> P>此外,GHCI在历史上已知有与C++代码连接的问题。例如,在某一点上,它不理解弱符号(通常由编译器结合内联函数和模板实例化产生)你可能会看到其中的一个问题。我建议向GHC团队提交一个bug报告。 包括一个带有Haskell库的C或C++库,一旦知道一些技巧,就很小。
我从中获得了核心,尽管它似乎过于复杂。你可以使用cabal(目前为1.25)和简单的构建类型(即没有特殊的设置.hs
),没有makefile,也没有像c2hs
这样的外部工具
要包含纯C库中的符号,请执行以下操作:
在cabal文件中,添加Include dirs:relative/path/to/headers/
或Include:relative/path/to/myheader.h
添加C-sources:relative/path/to/csources/c1.C、relative/path/to/csources/c2.C等
C++还有几个额外的位:
您可以将.cpp
文件添加到cabal文件中的C-sources
字段中
在Haskell需要访问的.cpp
文件中的所有函数上,添加extern“C”
,以避免名称混乱
将头文件中的所有非纯C代码用\ifdef\uu cplusplus…#endif
(参见n.m.的答案)包围起来
如果使用标准C++库,则需要将额外的库:STDC++/COD>添加到您的CABAL文件中,并使用<代码> GHC选项链接到<代码> G++<代码>:-PGMLG++ ./LI>
如果希望动态链接(即cabal repl
)起作用,您可能需要稍微调整在cabal文件中列出.c(pp)
文件的顺序。有关更多信息,请参阅
就是这样!您可以看到一个完整的工作示例,它同时适用于stack
和cabal
您能提供一个吗?变量太多,具体信息太少,无法诊断问题。@n.m.更新为an。使用共享库运行时,出现错误“没有这样的文件或目录libclib.so”可以通过在LD.LabyAuthPipe中放置LIclicli.So或在LD选项中指定安装目录。<代码> -RPAT/PAT/OT/LIbclib DR < /C>应该做这个把戏。在Haskell静态库中集成C++代码并不确定。我从未尝试过。这有什么问题?有一个成功集成的例子吗?在C++代码中,以相同的方式集成C++代码不起作用:在这种情况下,你得到什么错误消息?@ N.M。除非我可以为.so文件指定一个相对路径,这是不好的。这意味着库的用户也必须设置一个特定的路径,这是非常复杂的。在CLib
版本中,我不必设置LD_LIBRARY_PATH或LD options
来获取动态库