用Haskell库静态链接C ++库 [英] Statically link C++ library with a Haskell library
问题描述
安装:我有一个Haskell库 HLib
,它可以调用C / C ++后端 CLib
来提高效率。后端很小,专门用于 HLib
。 CLib
的接口将 通过 HLib
暴露出来。 HLib
测试, HLib
基准测试和第三方库取决于 HLib
不会直接对 CLib
进行FFI调用。从测试/基准/第三方lib的角度来看, HLib
应该纯粹是Haskell。这意味着在例如 HLib
测试的cabal文件部分中,不应该引用 -lCLib
, libCLib
等,在 HLib
上只有一个 build-depends
,并且可执行文件不应该需要查找动态 CLib
库。我需要能够在 HLib
和第三方库中生成并运行所有可执行文件,以及运行 cabal repl
for development。
原来, include-dirs
c-sources
和包括
CLib
已经发展成一个C ++库,我无法弄清楚如何轻松集成cabal。相反,我使用了自定义构建和Setup.hs的makefile,例如 。你可以在这里看到这个方法的一个小例子 1,2 。
在该例中,我无法在 HLib $ c中运行
cabal repl
$ c>因为加载不支持的档案。这实际上意味着我需要一个动态的C ++库,它非常简单,可以创建(在 CLib
makefile中有一条注释行)。但是,如果我制作动态C ++库,由于没有这样的文件或目录libclib.so, HLib
的测试在运行时失败。这是坏的(除了崩溃),因为测试可执行文件链接到动态库,这不是我想要的。
具体而言, 我试过的其他东西:这个答案 a>,这个答案(我无法编译), ,并阅读文档(导致重定位错误)。 目前我正在使用GHC-7.10.3 ,但如果这在8.0中更容易,那很好。 [1] 从 lol / challenges 。 b [2] 下载并运行 我从这个文章,尽管它看起来过于复杂。你可以使用cabal(目前是1.25)和 包含纯C库中的符号: C ++有一些额外的位: 就是这样!您可以在这里看到一个完整的工作示例,它可以与 Setup: I have a Haskell library Originally, In that example, I can't run Concretely, the tests for Other things I've tried: this answer, this answer (which I can't get to compile), this, and reading the docs (results in "relocation" errors). I'm using GHC-7.10.3 at the moment, though if this is significantly easier in 8.0, that's fine. [1] Simplified from lol/challenges. [2] Download and run Including a C or C++ library with a Haskell library is trivial once you know a few tricks. I got the core from this article, though it seems to overcomplicate things. You can use cabal (currently 1.25) with a To include symbols from a pure C library: There's a couple of extra bits for C++: That's it! You can see a complete working example here which works with both 这篇关于用Haskell库静态链接C ++库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! HLib
和 SimpleLib
都应该通过,我应该能够运行 cabal repl $ c $在$
hlib
和 simplelib
目录中都有
$ b ./ sandbox-init
。这将构建 HLib
(它隐式构建 CLib
和 SimpleLib
,这是一个Haskell库,它依赖于 HLib
。
Simple
构建类型(即没有特殊的 Setup.hs
),没有makefile ,并且没有外部工具,如 c2hs
。
Include-dirs:relative / path / to / headers /
或包含:relative / path / to / myheader.h
。
C-sources:relative / path /to/csources/c1.c,相对/路径/到/ csourc es / c2.c等。
。
.cpp
文件添加到 C-sources
字段。
.cpp
文件中添加 externC
以避免名称混乱。
#ifdef __cplusplus ... #endif $>包围头文件中的所有非纯C代码c $ c>(请参阅nm的答案)。
extra-libraries:stdc ++
ghc-options:-pgmlg ++
链接到 g ++
li>
.c(pp)
文件cabal文件,如果你想动态链接(即 cabal repl
)工作。有关详情,请参阅此故事单。
stack
和 cabal
。HLib
which makes calls to a C/C++ backend CLib
for efficiency. The backend is small and specialized for use with HLib
. The interface to CLib
will only be exposed through HLib
; HLib
tests, HLib
benchmarks and third party libraries depending on HLib
will not make direct FFI calls to CLib
. From the test/benchmark/3rd party lib perspective, HLib
should be appear purely Haskell. This means in the cabal file sections for, e.g., HLib
tests, there should be no references to -lCLib
, libCLib
, etc, only a build-depends
on HLib
, and that executables should not need to look for a dynamic CLib
library. I need to be able to build and run all executables in HLib
and third-party libs, as well as run cabal repl
for development.CLib
was written in pure C. Cabal has support for this case, and I can integrate CLib
into HLib
in precisely the manner described above by using include-dirs
, c-sources
, and includes
fields in the cabal file.CLib
has evolved into a C++ library, which I couldn't figure out how to get cabal to integrate easily. Instead, I resorted to a makefile with custom build and Setup.hs, like this. You can see a small example of this method here1,2.cabal repl
in HLib
because "Loading archives not supported". This really means I need a dynamic C++ library, which is simple enough to create (there's a commented line in the CLib
makefile to do it). If I do make the dynamic C++ library, however, the test for HLib
fails at runtime due to a "no such file or directory libclib.so". This is bad (in addition to the crash) because the test executable linked against the dynamic library, which is not what I want.HLib
and SimpleLib
should both pass, and I should be able to run cabal repl
in both the hlib
and simplelib
directories../sandbox-init
. This builds HLib
(which implicitly builds CLib
, and SimpleLib
, which is a Haskell library that depends on HLib
.Simple
build type (i.e. no special Setup.hs
), no makefile, and no external tools like c2hs
.
Include-dirs: relative/path/to/headers/
or Includes: relative/path/to/myheader.h
. C-sources: relative/path/to/csources/c1.c, relative/path/to/csources/c2.c, etc
.
.cpp
files to the C-sources
field in the cabal file. .cpp
files that Haskell needs access to, add extern "C"
to avoid name mangling.#ifdef __cplusplus ... #endif
(see n.m.'s answer).extra-libraries: stdc++
to your cabal file, and link with g++
using ghc-options: -pgmlg++
..c(pp)
files in the cabal file if you want dynamic linking (i.e. cabal repl
) to work. See this ticket for more information.stack
and cabal
.