静态链接C++;具有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中构建和运

设置:我有一个Haskell库
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
    来获取动态库