Dependency generator (ocamldep)

Chapter 13 | Dependency generator (ocamldep)

The `ocamldep` command scans a set of Objective Caml source files (`.ml` and `.mli` files) for references to external compilation units, and outputs dependency lines in a format suitable for the `make` utility. This ensures that `make` will compile the source files in the correct order, and recompile those files that need to when a source file is modified.
The typical usage is:

            ocamldep options *.mli *.ml > .depend

where `*.mli *.ml` expands to all source files in the current directory and `.depend` is the file that should contain the dependencies. (See below for a typical `Makefile`.)
Dependencies are generated both for compiling with the bytecode compiler `ocamlc` and with the native-code compiler `ocamlopt`.

13.1 | Options

The following command-line option is recognized by `ocamldep`.

`-I` directory
  Add the given directory to the list of directories searched for source files. If a source file `foo.ml` mentions an external compilation unit `Bar`, a dependency on that unit's interface `bar.cmi` is generated only if the source for `bar` is found in the current directory or in one of the directories specified with `-I`. Otherwise, `Bar` is assumed to be a module from the standard library, and no dependencies are generated. For programs that span multiple directories, it is recommended to pass `ocamldep` the same `-I` options that are passed to the compiler.
`-native`
  Generate dependencies for a pure native-code program (no bytecode version). When an implementation file (`.ml` file) has no explicit interface file (`.mli` file), `ocamldep` generates dependencies on the bytecode compiled file (`.cmo` file) to reflect interface changes. This can cause unnecessary bytecode recompilations for programs that are compiled to native-code only. The flag `-native` causes dependencies on native compiled files (`.cmx`) to be generated instead of on `.cmo` files. (This flag makes no difference if all source files have explicit `.mli` interface files.)

13.2 | A typical Makefile

Here is a template `Makefile` for a Objective Caml program.

    OCAMLC=ocamlc
    OCAMLOPT=ocamlopt
    OCAMLDEP=ocamldep
    INCLUDES=                 # all relevant -I options here
    OCAMLFLAGS=$(INCLUDES)    # add other options for ocamlc here
    OCAMLOPTFLAGS=$(INCLUDES) # add other options for ocamlopt here

    # prog1 should be compiled to bytecode, and is composed of three
    # units: mod1, mod2 and mod3.

    # The list of object files for prog1
    PROG1_OBJS=mod1.cmo mod2.cmo mod3.cmo

    prog1: $(PROG1_OBJS)
            $(OCAMLC) -o prog1 $(OCAMLFLAGS) $(PROG1_OBJS)

    # prog2 should be compiled to native-code, and is composed of two
    # units: mod4 and mod5.

    # The list of object files for prog2
    PROG2_OBJS=mod4.cmx mod5.cmx

    prog2: $(PROG2_OBJS)
            $(OCAMLOPT) -o prog2 $(OCAMLFLAGS) $(PROG2_OBJS)

    # Common rules
    .SUFFIXES: .ml .mli .cmo .cmi .cmx

    .ml.cmo:
            $(OCAMLC) $(OCAMLFLAGS) -c $<

    .mli.cmi:
            $(OCAMLC) $(OCAMLFLAGS) -c $<

    .ml.cmx:
            $(OCAMLOPT) $(OCAMLOPTFLAGS) -c $<

    # Clean up
    clean:
            rm -f prog1 prog2
            rm -f *.cm[iox]

    # Dependencies
    depend:
            $(OCAMLDEP) $(INCLUDES) *.mli *.ml > .depend

    include .depend