Ocaml compile time include file

let a: string = include_at_compile_time "foo.txt"

Is the above possible? I want the file included at compile time (and embedded as a string into the program).

XY problems: I have some WebGL vertex/fragment shaders. If possible, I’d prefer to just embed them into the ML source, instead of fetching them at runtime over http.

An easy way is to define a rule in whatever build system you are using to generate such as a file. See eg src/dune · master · POTTIER Francois / menhir · GitLab for an example using Dune.


Alternatively you can use ppx_blob to do this.

let txt: string = [%blob "./foo.txt"]

I embed a bunch of resources into the executable via opam - crunch

See the rule at the start of lib/dune and unpacking the assets via lib/assets.ml or use them directly at bin/cgi.ml#L115.

Does that help?

  1. Thanks everyone for responses.

  2. @Gopiandcode 's solution is closest to what I was looking for.


Huh, guess it makes sense there’d be a PPX rewriter for this. I’d have reached for cppo instinctively.

I am running into a problem with %blob.

I can include *.ml files fine, I can not include other types of files (dune/ocaml does not find them.)

I suspect (I’m making things up here now) that what happens is:

  1. .ml files are copied into _build/

  2. the include path starts searching from _build/* ?

I’m not sure. What’s going on? How does %blob interact with dune ?

It’s been a while since I used ppx_blob, but I think that’s the gist of it yes — the ppx might be being executed in the _build directory, so only files that are copied over are visible.

If you have a file that your ppx_blob is going to include you may need to declare it as a preprocessor dependency so dune knows to copy it:

(library (name ...)
 (preprocess (pps ppx_blob))
 (preprocessor_deps (file foo.txt)))
1 Like

The syntax may have recently changed. I had to use (preprocessor_deps vert.c frag.c) ; otherwise, everything worked flawlessly. Thanks!

Unrelated: I’m still curious where this directory it searches from is; I’m almost certain I calculated the correct location by looking at find _build/ , but I still could not get it to work.