Re: Чем плох рекурсивный make?
Dmitry E. Oboukhov -> debian-russian@lists.debian.org @ Wed, 1 Oct 2008 16:35:22 +0400:
AC>>>> gcc вызывают для того, чтобы сделать новый .o _вместо_ старого. Он про
AC>>>> старый вообще не думает, он его молча затирает. make - думает.
AC>>> и что с того что думает? мы что будем различия строить на том о чем
AC>>> думает какая-то программа во время работы?
AC>>> они каждая думает о своем.
AC>>> ладно хорошо другой пример:
AC>>> есть у нас makefile из которого вызывается другой makefile, но
AC>>> предположим не с программой make а с программой ?make
AC>>> рекурсия есть или рекурсии нет?
AC>> depends.
DEO> именно depends, о чем и говорю
DEO> и соответственно make на другой makefile точно такой же depends,
DEO> отличается от предыдущего depends одной буквой в названии
A>> Если ?make - это скрипт, выполняющий rm -f $1, то нет.
DEO> а это почему это? может у него задача стоит rm -f $1? (типичный make
DEO> clean)
Блин. Ты хочешь доказать мне, что можно придумать пример, где
рекурсивный вызов make не составляет проблем? Не вопрос, я и сам могу.
Вопрос в том, что в типичном случае проблемы будут. А в том, где не
будет, использование make - это из пушек по воробьям.
Или тебе настолько не нравится слово "рекурсивный", что ты не можешь
найти в себе сил выяснить, что оно значит в контексте обсуждаемой фразы
из четырех английских слов?
AC>>>> Если это не отличие, то ты не в курсе, зачем нужен make.
AC>>> он нужен чтобы собирать цели, а уже собранные игнорировать.
AC>> Отнюдь не игнорировать.
DEO> именно игнорировать, поскольку они уже собраны
Отнюдь не игнорировать. А как минимум использовать в рассуждении о том,
что надо и что не надо пересобирать. Очень возможно, что пересобрать, а
вовсе не проигнорировать, хотя уже собрано.
AC>> Шелловский скрипт unconditional сборки проекта проще соответствующего
AC>> мейкфайла. Потому что надо описать только команды сборки, а на
AC>> зависимости можно забить.
DEO> если ты на зависимости забьешь то у тебя не соберется
Соберется. Я две строчки местами поменяю (несколько раз), и соберется.
DEO> а и shell'овским скриптом тоже можно смотреть на даты файлов и
DEO> сравнивать их.
DEO> разницы тут ровно столько что в одном языке одно действие сделать проще
DEO> чем в другом
Ты слово unconditional не смог прочесть или найти в словаре?
AC>> Ясно. Не понял. Объяснить?
DEO> попробуй :)
Объясняю. Берем (для примера урезанный, существенное сохранено) вариант
того самого debian/rules, который тебе вроде как нравился.
install: configure install-stamp
install-stamp:
make -C .. install DESTDIR=debian/tmp
touch $@
Выполнили один раз. Результат, допустим, не понравился.
Изменяем проект (допустим, накладываем патч). Даже, допустим, собираем
результат. Там же, в проекте. Запускаем debian/rules install, дабы
заново собрать пакет (на самом деле, естественно, запускаем binary, а
оно позовет install - там это будет в еще два шага, я их не привел).
Вопрос. Какая версия будет в пакете в результате?
Для особо невнимательных сразу ответ. Старая. В смысле - та, которая
была, а не обновленная. Оно просто не попытается ничего инсталлировать.
Почему? Да потому что ему неоткуда знать, что там что-то изменилось.
Оно видит только, что есть файл install-stamp, а раз он есть, делать
ничего не надо.
То есть этот debian/rules - система _однократной_ сборки. В том смысле,
что гарантирует корректный результат только если сборка - первая. Может
быть, первая после debian/rules clean, а может, и только после
распаковки, этого я не проверял.
Можно его изменить так, чтобы он гарантированно каждый раз собирал
свежую версию. Но - фактически ценой отказа от функциональности make по
анализу "что надо собирать, а что - нет". При этом make для этой задачи
становится overkill'ом и потенциальным источником ошибок (где-то что-то
забыл почистить - и привет...)
AC>>>> Это как раз существенно более типичная иллюстрация к recursive make
AC>>>> considered harmful. Но в натуре, как правило вот ровно к этому.
AC>>> хармфул тут в голове макепейсателя а не в самом маке
AC>> Скажем так, избежать этих грабель при рекурсивном вызове make гораздо
AC>> труднее,
DEO> вызов внешнего make - нерекурсивный
Терминология используется не твоя, а авторов make. Dixi.
DEO> и грабли начинаются только там где два процесса пытаются работать с
DEO> одним ресурсом, обычный IPC
DEO> это в любом языке эти грабли есть где есть возможность создания
DEO> процессов и воздействия их друг на друга.
DEO> если например
DEO> makefile1 собирает либу1
DEO> makefile2 собирает либу2
DEO> makefile3 собирает либу1 и либу2 в пакет, вызывая makefile2 makefile1
DEO> то это нормально
Нет. Вон выше пример разжеван в деталях. Ровно такая ситуация, даже
без либы2.
Вернее, нет. Если makefile3 делает не make -f makefile1, а include
makefile1, то все нормально. Но если при этом они в разных директориях,
как в случае с debian/rules, то makefile1 надо писать очень специально,
сразу с расчетом на эту конструкцию. У меня есть один такой, да...
Повторяю. Специально писать надо makefile1, а не makefile3. Т.е. в
данном случае правками в debian/rules это не лечится. Более того,
_правками_ в makefile1, как правило, тоже - его надо именно что
специально _писать_. На практике с шансами потребуется два
А на практике, естественно, этого никто делать и не пытается (особенно,
если makefile1 сгенерирован, а не руками писан), а делают make -C dir.
AC>> У make, впрочем, есть и еще одна проблема. Она уже не имеет
AC>> отношения к рекурсивному вызову, но ноги ее растут примерно из той
AC>> же весьма куцей модели зависимостей, которую он реализует. Ее
AC>> тоже можно обойти, но это ВЕСЬМА нетривиально, и разумеется, НИКАК
AC>> не поддерживается встроенными правилами (т.е. встроенными
AC>> пользоваться при этом нельзя). Называется она "разные аргументы
AC>> командной строки".
DEO> все борьба с какими-то ветряными мельницами, то с шеллом то с мейком
DEO> повесили ярлык "рекурсивный" и сказали что плохо, теперь вот аргументы
DEO> комстроки не нравятся, лучше уж тогда вернуться к флейму про getopt ;)
Вот, блин, сразу видно, что мейком по назначению-то ты и не пользовался...
--
Artem Chuprina
RFC2822: <ran{}ran.pp.ru> Jabber: ran@jabber.ran.pp.ru
В теории нет различия между теорией и практикой. На практике - есть.
Reply to: