Embedding files in a binary

So this time, I’m asking for community input.

Problem

So, if you’ve been paying attention to the flow of the packages I’ve written, you might see a direction: write a web application, and let it run as a standalone application. However, what do you do about static files (CSS, JavaScript, etc)?

Solution 1: Install static files in a standard location

This is pretty straight forward, and seems to be a well-accepted practice for lots of types of files. For example, I think it’s recommended for Glade files. However, I have always felt a little awkward about it.

Solution 2: Embed the files in the binary

Overall, this has the benefit of allowing the binary to just be moved around without regard for the static files. That’s my main goal in this. It has a side benefit of minimizing file system access, which for my purposes is not that important. On the downside, it makes it more difficult to make changes (eg, a full recompile to change from blue to green).

I see two ways of accomplishing this.

Solution 2a: Code generator

Have a little utility that takes a file, and converts it to a Haskell file containing the file contents. Disadvantage: an extra step in the compile process. Advantage: you can make a dependency from foo-bar.txt to foo-bar_txt.hs so that your build program knows to automatically regenerate the files.

Solution 2b: Template Haskell

Advantage: simplicity. Disadvantage: you’ll need to touch your Haskell file each time you make a static file change.

I’ve implemented a simple version of this. It exports two functions: one for including a single file, one for an entire directory tree. The code is available on Github. I haven’t uploaded it to Hackage. This is my first stab at Template Haskell, so if you see any glaring mistakes please let me know.

Also, if people have any suggestions on which solution is best, or know of a different solution to this issue, please let me know!

Advertisements

5 Responses to “Embedding files in a binary”

  1. Don Stewart Says:

    Could you also just use Data.Binary to encode the contents as a string? http://www.haskell.org/haskellwiki/Compiling_in_constants

  2. cmcq Says:

    “objcopy” can embed files directly into your binary. Unfortunately this creates a requirement on an external tool and makes the build process more platform-specific. I’ve put C and Haskell examples at:

    http://community.haskell.org/~cmcq/objcopy/

  3. Liyang HU Says:

    http://en.wikipedia.org/wiki/Application_Bundle seems a sensible way of doing things. Kind of OS (X)-specific though. Regarding Linux, I wonder if http://en.wikipedia.org/wiki/Binfmt_misc can be made to work with directories rather than just files… Windows users are a bit screwed however.

  4. Felipe Says:

    It should be possible to create a tool that creates platform-specific installers from cabal files. We already have this kind of tools for some distros and probably could have for Windows and OS X, too. You would then just specify your files using the usual cabal “data-files” option.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: