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

    either extra-libraries: hdf5

    to my cache file and in both cases the resulting files .a, .so, .dyn_hi, .dyn_o, .hi and .o in dist/build

    are exactly the same dimensions as without using extra-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.

+3


source to share





All Articles