How do I statically compile a C library into a Haskell module that I can later load using the GHC API?
Here is my desired use case:
I have a single module package that reads HDF5 files and writes some data to Haskell records. The library uses a package to do this work bindings-hdf5
. Here is my bondage build-depends
. reader-types
is a module I wrote that defines the Haskell record types that contain data to read.
build-depends: base >=4.7 && <4.8
, text
, vector
, containers
, bindings-hdf5
, reader-types
Please note that my file cabal
is currently not using extra-libraries
or ghc-options
. I can load my module, src/Mabel.hs
in ghci, if I specify the required library hdf5_hl
:
ghci src/Mabel.hs -lhdf5_hl -L/long/nixos/path/lib
and inside ghci I can do my function fine.
Now what I want to do is compile this library / module into one compiled file, which I can later load using the GHC API in another Haskell program. By one file I mean that it should run even if the library hdf5_hl
doesn't exist on the system. Preferably, it also starts, even if text
, vector
and / or are containers
absent, but this is not essential because it reader-types
requires these types anyway. When loading a module with the GHC API, I want it to be loaded into an already compiled form and not run interpreted.
My goal for this is that I want the standalone file to act as a single, pre-compiled plugin file that is later loaded and executed by another Haskell executable. Other plugins may not use hdf5 at all, and the only package they guarantee to use reader-types
, which essentially defines the plugin interface types.
Hdf5 library on my system contains the following files: libhdf5_la.la
, libhdf5_hl.so
, libhdf5.la
, libhdf5.so
and similar files with the version number in the file name.
I have done a lot of searches but I am confused by all the cases I find. Here are some examples that I'm either sure don't fit my case or I can't tell.
- I don't want to compile a Haskell library for use with C or Python , just a Haskell program using the GHC API.
- I don't want to compile C wrappers for a C ++ library into a Haskell module , because the bindings already exist and the library is already a C library.
- I do not want to compile a library that is completely self-contained , because since I am loading its GHC API, I donβt need the GHC runtime included in the library. (I understand that plugins must be compiled with the same version of ghc that they will load into the GHC API).
- I do not want to compile the C bindings and the C library at the same time , because the C library is already compiled and the bindings specified in a separate package (
bindings-hdf5
). - The closest resource for what I want to do is this exchange on the mailing list from 2009. However, I added
extra-libraries: hdf5_hl
eitherextra-libraries: hdf5
to my cache file and in both cases the resulting files .a, .so, .dyn_hi, .dyn_o, .hi and .o indist/build
are exactly the same dimensions as without usingextra-libraries
, so I'm pretty sure it is does not work correctly.
What changes to my file cabal
do I need to make to create a standalone offline file that I can later download using the GHC API? If this is not possible, what are the alternatives?
Instead of using the GHC API, I am also open to using the library plugins
to load the plugin, the requirements they contain remain the same.
EDIT: I don't care what form the compiled "plugin" has to execute (I assume the object file is the correct path), but I want to dynamically load it from a separate executable at runtime and execute the functions it defines with known names and known types. The reason I want one file is because there will be other plugins eventually, and I want them all to behave the same without worrying about the paths and lib dependencies for each one. A compiled single file is an easier interface for this than zipping / unzipping archiving, which includes the Haskell object code and their dependencies.
source to share
No one has answered this question yet
See similar questions:
or similar: