Что мне не нравится в ocamlbuild.
2011-11-21 02:43 pmНаконец, теперь можно написать про 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.
Казалось бы, 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.
(no subject)
Date: 2011-11-21 05:32 pm (UTC)Т.е. хочется, чтобы при запуске в src/lib/libFoo пересобиралась только libFoo, а не всё, что от неё зависит?
(no subject)
Date: 2011-11-21 09:36 pm (UTC)(no subject)
Date: 2011-11-22 10:56 pm (UTC)(no subject)
Date: 2011-11-23 08:59 pm (UTC)С другой стороны, в ходе разработки можно либо не компилировать вообще, либо "ghc --make" в рамках конкретной директории.
(no subject)
Date: 2011-11-22 07:18 am (UTC)(no subject)
Date: 2011-11-22 03:22 pm (UTC)(no subject)
Date: 2011-11-23 08:58 pm (UTC)Он много чего про Standard ML рассказывал, но вот конкретно про компиляцию и зависимости я ничего не припомню. На что именно смотреть-то? Да, ML Basis организован хорошо, но какое это имеет отношение к вопросу? Чего я не вижу?
(no subject)
Date: 2016-05-14 06:06 pm (UTC)(no subject)
Date: 2016-05-19 08:17 pm (UTC)(no subject)
Date: 2011-11-24 04:37 am (UTC)(мне бы так везло.. а то все самому одному мозг ломать...)
лично у меня после обзорного знакомства с MLB создалось впечатление что там таких проблем нет и раздельная компиляция работает как положено... полагаю правда пронаблюдать это вживую возможно только в MLKit. насчет SML/NJ уверенности меньше но тоже возможно. ну а Mlton всегда компилирует только все - по идеологии своей) к сожалению из-за этого он несколько иначе воспринимает все и сложно сказать как было бы лучше...
(no subject)
Date: 2011-11-24 04:44 am (UTC)(no subject)
Date: 2011-12-29 11:13 pm (UTC)(no subject)
Date: 2011-12-30 08:58 pm (UTC)Надо порешать, спасибо :)