Does Findlib support camlp4?

Short answer: Yes, but there is only little documentation.

Since Findlib-0.4, there is some experimental camlp4 support. For example, the following compiler invocation chooses the revised syntax:

ocamlfind ocamlc -syntax camlp4r -package camlp4 -c
As you can see, camlp4 must be included as package, and the -syntax option must specify which syntax is selected (either camlp4o or camlp4r).

If you want to pass additional options to the preprocessor, you can use the -ppopt option:

ocamlfind ocamlc -syntax camlp4r -package camlp4 -ppopt pa_ifdef.cmo -c

From the toploop, the following commands work:

$ ocaml
        Objective Caml version 3.07+2
# #use "./topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;      to load a package
  #list;;                   to list the available packages
  #camlp4o;;                to load camlp4 (standard syntax)
  #camlp4r;;                to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();;         to force that packages will be reloaded
  #thread;;                 to enable threads
- : unit = ()
# #camlp4o;;            (* or camlp4r *)
/opt/godi/lib/ocaml/std-lib/camlp4: added to search path
/opt/godi/lib/ocaml/std-lib/camlp4/camlp4o.cma: loaded
        Camlp4 Parsing version 3.07+2
# _

The concept

If you have a -syntax option on the command line, ocamlfind will generate a -pp parameter and pass it to the invoked compiler. This is performed as follows: The specified packages are inspected under a certain set of predicates, the syntax predicates. The syntax predicates are syntax, preprocessor, and the predicates following -syntax. The predicate syntax simply means that the -syntax option has been specified. The predicate preprocessor means that the preprocessor command is being constructed. The predicates added by -syntax may be used to distinguish between syntax variants (currently camlp4o and camlp4r).

The packages are searched for a variable preprocessor; normally the camlp4 package defines it as (see its META file):

preprocessor = "camlp4 -nolib"
Now that the name of the preprocessor command is known, the arguments of the command are looked up. The META files are evaluated under the syntax predicates, and all archive variables are collected and passed as arguments to the preprocessor. For example, the camlp4 package defines:
archive(syntax,preprocessor,camlp4o) = "pa_o.cmo pa_op.cmo pr_dump.cmo"
archive(syntax,preprocessor,camlp4r) = "pa_r.cmo pa_rp.cmo pr_dump.cmo"
Note that the predicate preprocessor prevents ocamlfind from including these archives into the regular list of archives to link.

How to write a META file for your own syntax extension

Suppose you have two archives: pa_myext.cma contains the extension code of camlp4, and run_myext.cma contains runtime material that must be present in programs compiled with your extensions. Your META file should look as follows:

requires = "camlp4"
archive(syntax,toploop) = "pa_myext.cma run_myext.cma"
archive(syntax,preprocessor) = "pa_myext.cma"
archive(syntax,byte)    = "run_myext.cma"
archive(syntax,native)  = "run_myext.cmxa"
You may add dependencies on camlp4o or camlp4r if you have archives only working for one of the two syntax variants.

To compile a program using your syntax extension package, one should use:

ocamlfind ocamlc -package yourname -syntax variant ...


The package xstrp4 defines a syntax extension allowing $-substitutions in O'Caml strings. Version 1.0 of this package takes advantage from the new camlp4 support of findlib; you may have a look at it for an example.

You can find xstrp4 here.