dastapov: (Default)
[personal profile] dastapov
Как я уже говорил,
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-11 12:50 pm (UTC)
From: [identity profile] filonov.livejournal.com
Вывод довольно странный. Если ocamldep, заточенный под make, пытаются скрестить с "какой-то другой системой сборки", которая игнорирует даты обновления файлов, то почему это должно быть проблемой ocamldep?
Собственно и зависимость от .cmi не указывает все по той же причине - связка с make.
Там довольно нетривиально с заданием правил, генерирующих более чем один целевой файл одновременно.

(no subject)

Date: 2011-11-11 01:27 pm (UTC)
From: [identity profile] ximaera.livejournal.com
facepalm.gif

(no subject)

Date: 2011-11-11 01:33 pm (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Попробую тезисно:

Хочется взять какой-нибудь tup или redo или scons и собирать ocaml.

Без информации о зависимостях это делать нелья (ибо компилятор туп).

Без разбора исходников это делать нелья (т.к. язык сложный и, грубо говоря, регекспами это не сделаешь).

Единственная официальная идущая вместе с компилятором утилита для анализа зависимостей решает не общую задачу, а какую-то узкоспециальную, которая за пределом этой ниши нафиг не нужна. Отсюда вывод про то, что утилита - полная фигня.

Бонусом идет то, что собирать с приемлимым уровнем комфорта с помощью make любой сложный проект на ocaml, вобщем-то, практически нереально. Из-за того, что make не умеет зачитывать информацию о зависимостях на ходу.

То есть, повторюсь, проблема ocamldep именно в том, что он ориентирован на make. Из более подробного вывода можно было бы "натупить" правила для make, а вот наоборот сделать не получается.

(no subject)

Date: 2011-11-11 01:40 pm (UTC)
From: [identity profile] ximaera.livejournal.com
Ну хотя бы потому что кроме ocamldep, заточенного под make, в среде OCaml под системы сборки ничего не заточено, а жить как-то надо.

В предыдущем посте из этой серии мне сообщили, что, вроде как, код на OCaml не нужно собирать ничем, кроме ocamlbuild. Я так понимаю, никаких предпосылок для этого в спецификации языка нет, а есть проблемы с реализацией -- ну так почему бы их не поправить вместо того, чтобы городить ocamlbuild?

(no subject)

Date: 2011-11-11 04:50 pm (UTC)
From: [identity profile] filonov.livejournal.com
Единственная официальная идущая вместе с компилятором утилита для анализа зависимостей решает не общую задачу, а какую-то узкоспециальную, которая за пределом этой ниши нафиг не нужна. Отсюда вывод про то, что утилита - полная фигня.
Претензия имхо очень странная. Абсолютно любая программа за пределами своей ниши нафиг никому не нужна.
Программа делает то, на что расчитана. ocamldep как следует из его документации - генератор make-файлов.

То есть, повторюсь, проблема ocamldep именно в том, что он ориентирован на make.
Это не его проблема, это проблема тех, кто не пользуется make.

Для любителей странного есть ocamldep -modules который вполне поддается парсингу регэкспами.

(no subject)

Date: 2011-11-11 05:07 pm (UTC)
From: [identity profile] helvegr.livejournal.com
ghc -M (аналог ocamldep) тоже генерирует зависимость только от .hi файла (http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/separate-compilation.html#using-make), но не от .o, но при этом вся нужная для cross-module inlining информация помещается в .hi:
$ cat A.hs
module A
    where

a = "foo"
$ ghc -O2 -ddump-hi A.hs
[1 of 1] Compiling A                ( A.hs, A.o )

==================== FINAL INTERFACE ====================
interface main:A 7002
  interface hash: 4d16d97acc6ad66b377fa6561c4bb5db
  ABI hash: b5a50b19d49d3f75363a8d9e8dfe75f3
  export-list hash: 6dc11cf3948bebe8a7423d65a84dc7f0
  orphan hash: 693e9af84d3dfcc71e640e005bdc5e2e
  where
export main:A a
module dependencies:
package dependencies: base ghc-prim integer-gmp
orphans: base:GHC.Base base:GHC.Float base:GHC.Num
family instance modules:
import base:Prelude 6cb91ac29334c0836b27c462c75636c7
f34b0179b148d8bcb96cf9d6533ba4cd
  a :: [GHC.Types.Char]
    {- Unfolding: (GHC.Base.unpackCString# "foo") -}
vectorised variables:
vectorised tycons:
vectorised reused tycons:

(no subject)

Date: 2011-11-11 05:09 pm (UTC)
From: [identity profile] dendik.livejournal.com
Бонусом идет то, что собирать с приемлимым уровнем комфорта с помощью make любой сложный проект на ocaml, вобщем-то, практически нереально. Из-за того, что make не умеет зачитывать информацию о зависимостях на ходу.


На самом деле, в GNU make (а может, и не только в нём) есть на эту тему костыль. Он состоит вот в чём: если в Makefile есть include или -include, и ещё есть правило для делания файла, который include'ится, то тогда, если это правило говорит, что этот файл нужно переделать, то после его переделки make перезапускается и подсасывает новый файл.

(no subject)

Date: 2011-11-11 05:24 pm (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Что, вобщем-то, еще раз подтверждает мой более ранний тезис о том, что все, что для пользователей-программистов сделано по остаточному принципу.

Компилятор сам не компилирует, ocamldep сделан абы как (что с -modules, что без).
Edited Date: 2011-11-11 05:28 pm (UTC)

(no subject)

Date: 2011-11-11 05:27 pm (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Если я правильно понимаю, это нифига не спасает от случая: вот автогенерируемый .ml, который делается из .mly, а вот .depend, который зависит от всех .ml в текущей директории, и когда мы запускаем make, надо, чтобы сначала выполнилось .mly -> .ml, потом запусился ocamldep, а потом make перезапустил себя, перечитав зависимости.

Ага?

(no subject)

Date: 2011-11-11 05:31 pm (UTC)
From: [identity profile] filonov.livejournal.com
Програмисты винят програмистов, в том, что они плохо пишут программы для програмистов :)

(no subject)

Date: 2011-11-11 05:40 pm (UTC)
From: [identity profile] dendik.livejournal.com
Я давненько не брал в руки этих шашек, но по идее оно всё же должно работать...

Ну или на худой конец можно заставить make запускать генерацию зависимостей на совсем каждый запуск, например:
.PHONY: .depend
.depend:
   $(MAKE) ml
   ocamldep ...

(no subject)

Date: 2011-11-11 05:57 pm (UTC)
From: [identity profile] filonov.livejournal.com
Пример неудачный. Все решается однократным запуском
make parser.ml
make depend

(no subject)

Date: 2011-11-12 08:51 am (UTC)
From: (Anonymous)
В свое время мне пришлось парсить вывод ocamldep и генерить правильный для своей системы сборки.

(no subject)

Date: 2011-11-12 03:28 pm (UTC)
From: [identity profile] balmerdx.livejournal.com
А зачем ocaml пользоваться? В нём даже int кривой.

(no subject)

Date: 2011-11-14 07:44 am (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Пример как раз очень показательный. Чтобы было более очевидно, что это - выполнение работы make вручную, предположим, что у нас в проекте 10 мест, в которых надо сказать make parser.ml, make lexer.ml.

Да, и разумеется это не однократный запуск. Это приходится делать перед каждой сборкой.
Edited Date: 2011-11-14 07:48 am (UTC)

(no subject)

Date: 2011-11-14 07:47 am (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Прямо как в анекдоте: "А верблюд и говорит: 'А что у меня вообще прямое?'"

(no subject)

Date: 2011-11-14 08:10 am (UTC)
From: [identity profile] filonov.livejournal.com
А зачем делать это перед каждой сборкой?

(no subject)

Date: 2011-11-14 08:25 am (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
чтобы получить правильные зависимости, вестимо.

Иначе, если поменялся parser.mll или lexer.mly, зависимости будут неправильные.

(no subject)

Date: 2011-11-14 08:29 am (UTC)
From: [identity profile] filonov.livejournal.com
Далеко не каждое изменение меняет зависимости, еще меньше правок меняют зависимости так, что сборка ломается.

Если вам это действительно надо (мне вот ни разу не понадобилось) - как уже сказали выше, пускать make depend автоматически при каждой сборке.

(no subject)

Date: 2011-11-14 08:35 am (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Вот, например, системе continuous integration будет пофиг, что, якобы, далеко не каждое изменение должно менять зависимости. В один прекрасный день она просто сломается без всякого повода, если не делать make $(autogenerated_files) & make depend перед каждым билдом.

Особенно чудесно будет, если в результате изменения какой-то автогенерируемый файл перестал существовать (разработчик его удалил). В этом случае даже make depend не спасет. (Да, я знаю, что мы уже начинаем переходить в область обсуждения чистого make)

(no subject)

Date: 2011-11-14 08:47 am (UTC)
From: [identity profile] filonov.livejournal.com
Дискуссия приняла странный вид. Разработчик всегда может поломать сборку тем или иным способом. вместе с тем есть формализуемые способы этого не делать. В чем собственно проблема?

(no subject)

Date: 2011-11-14 09:03 am (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Дискуссия приняла странный вид. Разработчик всегда может поломать сборку тем или иным способом. вместе с тем есть формализуемые способы этого не делать.

Да, например - использовать что-то другое место make. Но в случа с ocaml это сложно, так как ocaml => ocamldep => только make

Edited Date: 2011-11-14 09:07 am (UTC)

(no subject)

Date: 2011-11-14 09:07 am (UTC)
From: [identity profile] filonov.livejournal.com
При использовании make ломать сборку так же совершенно необязательно. Я пробовал

(no subject)

Date: 2011-11-14 09:09 am (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
ОК. Сойдемся на том, что в моем СССР потребность в колбасе все-таки есть :)

(no subject)

Date: 2011-11-14 09:16 am (UTC)
From: [identity profile] filonov.livejournal.com
Ну так с этим никто и не спорит. Речь шла о том, что требовать от генератора make-файлов со всеми система сборки подряд слегка неразумно.

(no subject)

Date: 2011-11-14 09:25 am (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Я на это смотрю под другим углом: превращать единственный существующий инструмент анализа зависимостей в генератор-только-make-файлов было со стороны авторов toolchain-а слегка неразумно.
Edited Date: 2011-11-14 09:25 am (UTC)

(no subject)

Date: 2011-11-14 09:30 am (UTC)
From: [identity profile] filonov.livejournal.com
Если это покрывает все потребности разработчиков - то почему нет? Совершенно обычная ситуация в opensource

Profile

dastapov: (Default)
Dmitry Astapov

May 2022

M T W T F S S
       1
2345678
9101112131415
161718 19202122
23242526272829
3031     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags