Search code examples
haskellexecutablecabalpandoc-citeproc

Building a self-contained binary executable in Haskell with the dependency pandoc-citeproc


I'm trying to compile a self-contained executable for a CLI tool written in Haskell. I followed this example to automatically build the executables for different operating systems with Github Actions using Cabal v3.2 and ghc v8.10.3.

This seems to work well and the executables do function superficially, but when actually applied on data, I get the following error message for the Linux version (I did not test the Windows build, but a colleague confirmed that the MacOS version has the same problem):

myprogram-0.3.2-Linux-ghc-8.10.3: 
/home/runner/.cabal/store/ghc-8.10.3/pandoc-citeproc-0.17.0.2-
0607b6a3d51d41b0211d235af7fcf6eeb452dc6738775583dac1146860db61b1/
share/locales/locales-en-US.xml: openBinaryFile: does not exist (No such file or directory)

This tells me, that pandoc-citeproc, on which I depend for BibTeX file parsing, has some additional data-files that do not get packed into the exectuable. Indeed I found the following sentence in the cabal-install documentation:

Note that copied executables are not self-contained, since they might use data-files from the store. source

I did also read in the pandoc documentation, that it can be build in a way to already include these extra files.

It is possible to compile pandoc such that the data files pandoc uses are embedded in the binary. The resulting binary can be run from any directory and is completely self-contained. With cabal, add -fembed_data_files to the cabal configure or cabal install commands. With stack, use --flag pandoc:embed_data_files. source

How do I build an executable with cabal install to prevent the error message above? I hope this is possible and I'm not missing something crucial here.

I tried

cabal install exe:myprogram --install-method=copy --overwrite-policy=always -fembed_data_files

to no avail.


Solution

  • Adding the embed_data_files flag in the cabal install exe:myprogram command won't work, as cabal-install will pass it to your executable, rather than forwarding it to pandoc-citeproc. The most convenient way to set it up for good is through the cabal.project file. If you don't have one, create it with the following minimal contents:

    packages: ./*.cabal
    
    package pandoc-citeproc
        flags: +embed_data_files
    

    cabal-install will then recompile pandoc-citeproc dependency with the flag next time you ask for a build.