Как я уже говорил,
ocamldep делает слишком много допущений и пытается быть хитрее, чем на
самом деле нужно.
Например, ocamlopt при компиляции реализации модуля baz.ml генерирует объектный файл baz.o и метаданные baz.cmx.
Ocamldep это знает, что считает, что всем зависимым модулям достаточно
прописать зависимость _только_ от baz.cmx - мол, один фиг оба файла
генерируются одновременно.
Смотрите, к чему это приводит
То есть, я поменял исходный файл, перекомпилировал его, baz.o
изменился, а baz.cmx остался точно таким же. Для make это все равно -
он смотрит только на время модификации файла, поэтому make может
использовать информацию о зависимостях, которую генерирует ocamldep.
Для ocamlbuild это тоже не страшно, так как он содержит кусок кода,
который явно исправляет этот баг.
Но если у вас не make и не ocamlbuild, а какая-то другая система
сборки, которая проверяет еще и md5sum файла, то она решит, что модуль
не поменялся, и не будет пересобирать все зависимые модули! Учитывая,
что интерфейс модуля вобщем-то не поменялся (см. md5sum файла
baz.cmi), это решение выглядит логичным - в конце-концов новая
реализаця понадобится только на этапе линковки, правильно?
Неправильно! Из-за cross-module inlining _нужно_ пересобирать все
зависимые модули, иначе при линковке будет ошибка о "inconsistent
assumptions over interface Blah". А отключить inlining для ускорения
dev build-ов - нельзя.
Что же мы имеем в сухом остатке? Ocamldep пытается абстрагировать нас
от подробностей процесса сборки, но получается только хуже. Вместо
облегчения процесса сборки он его усложняет - приходится держать в уме
и подробности о том, как работает компилятор, и о том, что умалчивает
ocamldep. Leaky abstractions в чистом виде.
Вывод: инструменты более низкого уровня, чем ocamlbuild -
ocamlbuild и непосредственно компилятор ocaml - использовать
противопоказано, посколько в них полно мелких и крупных косяков,
которые исправляются только на следующих уровнях абстракции.
А никакого другого инструмента, кроме ocamldep - нет.
ocamldep делает слишком много допущений и пытается быть хитрее, чем на
самом деле нужно.
Например, ocamlopt при компиляции реализации модуля baz.ml генерирует объектный файл baz.o и метаданные baz.cmx.
Ocamldep это знает, что считает, что всем зависимым модулям достаточно
прописать зависимость _только_ от baz.cmx - мол, один фиг оба файла
генерируются одновременно.
Смотрите, к чему это приводит
adept> echo 'let baz = "baz"' > baz.ml adept> ocamlopt -c baz.ml adept> md5sum baz.c* baz.o ca6ab45ef85dd930e7f8e29ee4eddf8f baz.cmi 617e472bd3854192a30c443e313b2757 baz.cmx 894e61c407ac77f5b5f813008aec38e3 baz.o
adept> echo 'let baz = "baz baz baz"' > baz.ml adept> ocamlopt -c baz.ml adept> md5sum baz.c* baz.o ca6ab45ef85dd930e7f8e29ee4eddf8f baz.cmi 617e472bd3854192a30c443e313b2757 baz.cmx d05d63f7d7fa0f638982ef3d8a0eacf0 baz.o
То есть, я поменял исходный файл, перекомпилировал его, baz.o
изменился, а baz.cmx остался точно таким же. Для make это все равно -
он смотрит только на время модификации файла, поэтому make может
использовать информацию о зависимостях, которую генерирует ocamldep.
Для ocamlbuild это тоже не страшно, так как он содержит кусок кода,
который явно исправляет этот баг.
Но если у вас не make и не ocamlbuild, а какая-то другая система
сборки, которая проверяет еще и md5sum файла, то она решит, что модуль
не поменялся, и не будет пересобирать все зависимые модули! Учитывая,
что интерфейс модуля вобщем-то не поменялся (см. md5sum файла
baz.cmi), это решение выглядит логичным - в конце-концов новая
реализаця понадобится только на этапе линковки, правильно?
Неправильно! Из-за cross-module inlining _нужно_ пересобирать все
зависимые модули, иначе при линковке будет ошибка о "inconsistent
assumptions over interface Blah". А отключить inlining для ускорения
dev build-ов - нельзя.
Что же мы имеем в сухом остатке? Ocamldep пытается абстрагировать нас
от подробностей процесса сборки, но получается только хуже. Вместо
облегчения процесса сборки он его усложняет - приходится держать в уме
и подробности о том, как работает компилятор, и о том, что умалчивает
ocamldep. Leaky abstractions в чистом виде.
Вывод: инструменты более низкого уровня, чем ocamlbuild -
ocamlbuild и непосредственно компилятор ocaml - использовать
противопоказано, посколько в них полно мелких и крупных косяков,
которые исправляются только на следующих уровнях абстракции.
А никакого другого инструмента, кроме ocamldep - нет.
(no subject)
Date: 2011-11-12 03:28 pm (UTC)(no subject)
Date: 2011-11-14 07:47 am (UTC)