# Глава 13. Генератор зависимостей (осаmldep)

Команда `ocamldep` просматривает наборы исходных текстов Objective Caml (`.ml` и `.mli`) в поисках ссылок на внешние единицы компиляции и выводит строки завсисмостей в формате, пригодном для инструмента `make`. Она обеспечивает правильный порядок компиляции исходных текстов и рекомпиляцию только измененных файлов.

Как правило, `ocamldep` используется следующим образом:

    ocamldep <параметры> *.mli *.ml > .depend

где `*.mli` и `*.ml` соответсвуют всем файлам с исходным текстом в текущем каталоге, а `.depend` - файл содержащий список зависимостей (см. ниже типичный `Makefile`).

Зависимости генерируются как для компилятора байткода `ocamlc`, так и для компилятора внутреннего кода `ocamlopt`.

## 13.1 Параметры

`ocamldep` знает следующие параметры командной строки:

-I directory

  Добавляет directory к списку каталогов, в которых ищутся файлы с исходными текстами. Если файл `foo.ml` ссылается на внешнюю единицу компиляции `Bar`, зависимость от интерфейса `bar.cmi` устанавливается только в том случае, когда соответствующий исходный текст удается обнаружить в либо в текущем каталоге, либо в одном из указанных с помощью параметра `-I`. В противном случае `Bar` считается модулем стандартной библиотеки, и зависимость не генерируется. Для программ, исходные тексты которых рассредоточены по разным каталогам рекомендуется передавать `ocamldep` те же параметры `-I`, что и компилятору.

-native

  Создaвать зависимости только для программы во внутреннем коде (без версии в байткоде). Если файл реалиазции ( `.ml`) не имеет файла интерфейса (`.mli`), `ocamldep` генерирует зависимости, исходя из содержания компилированного файла с байткодом (`.cmo`), что позволяет отловить изменения интерфейса, но может повлечь за собой ненужные перекомпиляции байткола для программ, которые предполагается компилировать только во внутренний код. Параметр `-native` приводит к тому, что для генерации зависимостей используются объектные файлы с внутренним кодом (`.cmx`). Если у всех исходных текстов есть файлы интерфейсов, этот параметр ни на что не влияет.

## 13.2 Типичный Makefile

Ниже приведен шаблон `Makefile` для программы на Objective Caml.

    OCAMLC=ocamlc
    OCAMLOPT=ocamlopt
    OCAMLDEP=ocamldep
    INCLUDES=                 # все необходимые параметры -I
    OCAMLFLAGS=$(INCLUDES)    # все остальные параметры ocamlc
    OCAMLOPTFLAGS=$(INCLUDES) # все остальные параметры ocamlopt

    # prog1 компилируется в байткод и включает три
    # модуля: mod1, mod2 and mod3.

    # Список объектных файлов для prog1
    PROG1_OBJS=mod1.cmo mod2.cmo mod3.cmo

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

    # prog2 компилируется во внутренний код и включает два
    # модуля: mod4 and mod5.

    # Список объектных файлов для prog2
    PROG2_OBJS=mod4.cmx mod5.cmx

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

    # Общие правила
    .SUFFIXES: .ml .mli .cmo .cmi .cmx

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

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

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

    # Очистка
    clean:
            rm -f prog1 prog2
            rm -f *.cm[iox]

    # Зависимости
    depend:
            $(OCAMLDEP) $(INCLUDES) *.mli *.ml > .depend

    include .depend