dastapov: (Default)
Dmitry Astapov ([personal profile] dastapov) wrote2011-11-21 02:43 pm
Entry tags:

Что мне не нравится в ocamlbuild.

Наконец, теперь можно написать про ocamlbuild.

Казалось бы, ocamlbuild весь из себя красив и пушист, и в простом
случае можно сказать "ocamlbuild main.native" и в две секунды получить
работающий бинарник - чего еще желать простому разработчику?.

Мои претензии к нему заключаются в следующем:

1. Информация о сборке размазывается по отдельным файлам: состав
библиотеки помещается в libname.mllib или .mlpack, куча метаданных
помещается в _tags, правила сборки помещаются в myocamlbuild.ml.
Читать это сложнее, чем читать среднестатистический Makefile или его
аналог.

2. Всегда надо запускать ocamlbuild только в корне проекта. Если у вас
развесистый проект, и вы редактируется исходники в foo/bar/baz/bah, вы
не можете взять и запустить ocamlbuild прямо там. Надо пойти в корень
проекта и сделать ocamlbuild foo/bar/baz/bah/main.native

3. Чтобы собрать все-все-все в проекте, в котором N библиотек и M
бинарников, надо либо указать их все в качестве аргумента для
ocamlbuild, либо создать в корне файл .itarget, в котором перечислены
все 100500 целей. К сожалению, лично у меня это почему-то периодически
не работало :(

4. Чтобы собрать .cmi модуля, у которого нет .mli, ocamlbuild зовет
компилятор два раза - один раз ocamlc для сборки .cmi, второй раз
ocamlopt/ocamlc для сборки .cmx или .cmo. Если таких файлов много -
это выливается в ощутимый проигрыш по времени.

5. Ocamlbuild использует ocamldep, и в результате из-за особенностей
работы последнего ocamlbuild может пересобирать больше, чем реально
требуется. Хорошо хоть, что ocamlbuild знает про все "детские болезни"
ocamldep, и пытается по мере сил их компенсировать. В частности,
ocamlbuild корректно обрабатывает ситуации, в которых .o меняется, а
.cmx - нет

6. Ocamlbuild пересобирает модули, когда в этом нет необходимости.
Напрмер, у нас есть main.ml и test.ml, и они оба используют test.ml. Я
неоднократно наблюдал, как при вызове "ocamlbuild main.native &&
ocamlbuild test.native" модуль test.ml компилируется дважды. Это
происходит не всегда, и я так и не докопался, почему. В то же время,
при "ocamlbuild main.native test.native" этого никогда не происходит(?)

Bottom line: перевести большой существующий проект на ocamlbuild -
морока еще та. Эксперименты на среднего размера подмножестве
исходников показали, что надо будет много всего делать руками (писать
.mllib, писать _tags, создавать свой myocamlbuild.ml, возможно
ковыряться в самом ocamlbuild). В случае проблем приходится копаться в
трех слоях оберток - в ocamldep, в ocamlfind и разбираться с тем, как
работает ocamlopt.

Post a comment in response:

If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting