如何将C库静态编译为Haskell模块,以后可以使用GHC API加载?

时间:2014-10-18 20:26:25

标签: haskell ghc cabal

这是我想要的用例:

我有一个包含单个模块的软件包,可读取HDF5文件并将其部分数据写入Haskell记录。为了完成这项工作,该库使用bindings-hdf5包。这是我的阴谋集团build-dependsreader-types是我编写的一个模块,它定义了包含读入数据的Haskell记录的类型。

build-depends:         base >=4.7 && <4.8
                     , text
                     , vector
                     , containers
                     , bindings-hdf5
                     , reader-types

请注意,我的cabal文件目前不使用extra-librariesghc-options。只要我指定所需的src/Mabel.hs库,我就可以在ghci中加载我的模块hdf5_hl

ghci src/Mabel.hs -lhdf5_hl -L/long/nixos/path/lib

在ghci中,我可以很好地运行我的功能。

现在,我想要做的是将这个库/模块编译成一个编译后的文件,稍后我可以在另一个Haskell程序中加载GHC API。通过单个文件,我的意思是即使系统上不存在hdf5_hl库,它也需要运行。优选地,即使textvector和/或containers丢失,它也会运行,但这不是必需的,因为reader-types无论如何都需要这些类型。使用GHC API加载模块时,我希望它以已编译的形式加载,而不是运行解释。

我这样做的目的是希望自包含文件充当单个预编译的插件文件,该文件稍后由不同的Haskell可执行文件加载和执行。其他插件可能根本不使用hdf5,他们保证使用的唯一包是reader-types,它基本上定义了插件接口类型。

我系统上的hdf5库包含以下文件:libhdf5_la.lalibhdf5_hl.solibhdf5.lalibhdf5.so以及文件名中包含版本号的类似文件

我做了很多谷歌搜索,但我对所发现的所有边缘情况感到困惑。以下是一些我不确定不适合我的情况的例子,或者我说不出来。

  • 我不想compile a Haskell library to use from C or Python,只想使用GHC API的Haskell程序。
  • 我不想compile C wrappers for a C++ library into a Haskell module因为绑定已经存在且库已经是C库了。
  • 我不想编译完全self-contained的库,因为我用GHC API加载它,我不需要库中包含GHC运行时。 (我的理解是插件必须使用相同的ghc版本进行编译,它们将在GHC API中加载)。
  • 我不想compile C bindings and the C library at the same time因为已经编译了C库,并且在单独的包(bindings-hdf5)中指定了绑定。
  • 我想要做的最接近的资源是2009年邮件列表上的this exchange。但是,我在我的cabal文件中添加了extra-libraries: hdf5_hlextra-libraries: hdf5,在这两种情况下dist/build中生成的.a,.so,.dyn_hi,.dyn_o,.hi和.o文件的大小与不使用extra-libraries的大小完全相同,所以我确信它不起作用正确。

我需要对cabal文件进行哪些更改才能创建一个自包含的独立文件,以后可以使用GHC API加载?如果这是不可能的,有哪些替代方案?

我也可以使用plugins库来加载插件,而不是使用GHC API,但是自包含的要求仍然是相同的。

编辑:我不关心编译的“插件”必须采用什么形式(我假设目标文件是正确的方式),但我想在运行时从单独的可执行文件动态加载它并执行它定义的已知函数名称和已知类型。我想要单个文件的原因是最终会有其他不同的插件,我希望它们的行为方式相同,而不必担心每个插件的lib路径和依赖关系。编译的单个文件是一个比执行此操作更简单的接口,而不是压缩/解压缩包含Haskell对象代码及其依赖项的存档。

0 个答案:

没有答案