mcrunch

mcrunch is a command-line tool that embeds files into OCaml source code. It reads one or more files and produces an OCaml module where each file's contents are encoded as a hexadecimal string array (or list or a single string). The generated module can be statically linked into an OCaml program, giving it access to the file contents at runtime without any I/O operations.

This is useful for embedding static assets (configuration files, templates, certificates, binary data) directly into an OCaml binary.

Installation

$ opam install mcrunch

Usage

The simplest invocation takes a file and writes an OCaml module to stdout:

$ mcrunch -f foo.txt
let foo_txt = [| "\x66\x6f\x6f\x0a" |]

The OCaml binding name is derived from the filename, with characters like . and % replaced by underscores. You can also specify the binding name explicitly using the name:filename syntax:

$ mcrunch -f contents:foo.txt
let contents = [| "\x66\x6f\x6f\x0a" |]

Multiple files can be crunched into a single module:

$ mcrunch -f foo.txt -f bar.txt -o assets.ml

If a filename contains the character :, use the prefix -: to let mcrunch infer the name automatically:

$ mcrunch -f -:path:to:file

Options

$ mcrunch -f foo.txt --with-comments
let foo_txt = [| "\x66\x6f\x6f\x0a" |]                                                 (* foo.             *)

Note that comments are not supported for --string output. A warning is printed on stderr:

$ mcrunch --string --with-comments -f foo.txt
Comments are not supported for string output. Not outputting comments.
let foo_txt = "\x66\x6f\x6f\x0a"

Example

Given two files index.html and style.css, you can generate an OCaml module that embeds both:

$ mcrunch -f index.html -f style.css -o static.ml

The resulting static.ml contains two bindings, index_html and style_css, each holding the full file contents as a string array. You can then reference these values from your OCaml program and reconstruct the original content with String.concat "" (for arrays, Array.to_list first).

A whole tree of assets can be embedded at once, optionally restricted to some extensions:

$ mcrunch -d static -e html -e css -o static.ml
let static_index_html = [| … |]
let static_style_css = [| … |]

When the file to serve is only known at run-time, --lookup gives the module a function to reach it by path, and lets mcrunch name the bindings so that any filename can be crunched:

$ mcrunch -d static -s --lookup -o static.ml
let d_0 = "…"
let d_1 = "…"

let read = function
  | "static/index.html" -> Some d_0
  | "static/style.css" -> Some d_1
  | _ -> None

With --string, read hands back the string literal itself: nothing is concatenated or copied, and the contents stay where the linker put them.