forum.wfido.ru  

Вернуться   forum.wfido.ru > Прочие эхи > RU.UNIX.BSD

Ответ
 
Опции темы Опции просмотра
  #1  
Старый 11.05.2018, 06:41
Victor Sudakov
Guest
 
Сообщений: n/a
По умолчанию Makefile

Victor Sudakov написал(а) к All в May 18 08:37:32 по местному времени:

Dear All,

Как правильно написать Makefile на тот случай, если программа генерирует одновременно два файла, чтобы при этом она не запускалась дважды даже при -j2 и больше?

==============================================================
.MAKE.JOBS= 2
all: result

foo bar: source
touch foo bar

result: foo bar
cat foo bar > result

clean:
rm -f foo bar result
==============================================================

Вышеприведенный пример запускает touch дважды.

Читал https://www.gnu.org/savannah-checkou...e-Outputs.html
но там настолько ужас-ужас, неужели проще никак? Хотелось бы в рамках BSD make.

Victor Sudakov, VAS4-RIPE, VAS47-RIPN
--- GoldED+/BSD 1.1.5-b20160322-b20160322
Ответить с цитированием
  #2  
Старый 11.05.2018, 10:12
Alex Korchmar
Guest
 
Сообщений: n/a
По умолчанию Re: Makefile

Alex Korchmar написал(а) к Victor Sudakov в May 18 08:52:33 по местному времени:

From: Alex Korchmar <noreply@linux.e-moe.ru>

Victor Sudakov <Victor.Sudakov@f49.n5005.z2.fidonet.org> wrote:

VS> Как правильно написать Makefile на тот случай, если программа генерирует
VS> одновременно два файла, чтобы при этом она не запускалась дважды
То есть сперва мы специально запускаем дважды, потом пытаемся это сломать?

VS> но там настолько ужас-ужас, неужели проще никак?
То что ты хочешь - это какая-то заведомо вредная херня.
Разумеется она не делается просто.

Если файлы зависят друг от друга, это надо просто описать как зависимость.

> Alex

--- ifmail v.2.15dev5.4
Ответить с цитированием
  #3  
Старый 11.05.2018, 11:22
Eugene Grosbein
Guest
 
Сообщений: n/a
По умолчанию Re: Makefile

Eugene Grosbein написал(а) к Victor Sudakov в May 18 15:02:15 по местному времени:

11 мая 2018, пятница, в 06:37 NOVT, Victor Sudakov написал(а):

VS> Как правильно написать Makefile на тот случай, если программа генерирует
VS> одновременно два файла, чтобы при этом она не запускалась дважды даже при -j2 и
VS> больше?
VS> ==============================================================
VS> .MAKE.JOBS= 2
VS> all: result
VS> foo bar: source
VS> touch foo bar
VS> result: foo bar
VS> cat foo bar > result
VS> clean:
VS> rm -f foo bar result
VS> ==============================================================
VS> Вышеприведенный пример запускает touch дважды.

Решение зависит от того, почему именно мы не хотим запускать touch дважды,
так как лекарство не должно быть хуже болезни.

Например, такой вариант (не тестировал):

.MAKE.JOBS?= 2
all: result

foo: source
.if ( ${.MAKE.JOBS} = 1 )
touch foo bar
.else
make -j1 foo bar
.endif

bar: foo
[ -f $@ ] || make -j1 foo

Eugene
--
Choose no life
--- slrn/1.0.2 (FreeBSD)
Ответить с цитированием
  #4  
Старый 11.05.2018, 11:41
Victor Sudakov
Guest
 
Сообщений: n/a
По умолчанию Makefile

Victor Sudakov написал(а) к Alex Korchmar в May 18 14:01:40 по местному времени:

Dear Alex,

11 May 18 08:52, Alex Korchmar wrote to me:

VS>> Как правильно написать Makefile на тот случай, если программа
VS>> генерирует одновременно два файла, чтобы при этом она не
VS>> запускалась дважды
AK> То есть сперва мы специально запускаем дважды, потом пытаемся это
AK> сломать?

Почему "специально запускаем дважды"? Просто программка такая, что результатом переработки исходника являются сразу и одновременно 2 файла, её дважды запускать вредно.

VS>> но там настолько ужас-ужас, неужели проще никак?
AK> То что ты хочешь - это какая-то заведомо вредная херня.
AK> Разумеется она не делается просто.

Видимо не настолько вредная, её периодически хотят, например в
https://stackoverflow.com/questions/...-a-single-rule
и в gmake даже есть изящный (хотя и ограниченный) способ:
https://www.cmcrossroads.com/article...tputs-gnu-make

AK> Если файлы зависят друг от друга, это надо просто описать как
AK> зависимость.

А они (файлы foo и bar) не зависят друг от друга, они зависят только от файла source.
А вот result уже зависит от foo и от bar одновременно.

Victor Sudakov, VAS4-RIPE, VAS47-RIPN
--- GoldED+/BSD 1.1.5-b20160322-b20160322
Ответить с цитированием
  #5  
Старый 11.05.2018, 12:01
Victor Sudakov
Guest
 
Сообщений: n/a
По умолчанию Makefile

Victor Sudakov написал(а) к Eugene Grosbein в May 18 14:25:56 по местному времени:

Dear Eugene,

11 May 18 15:02, you wrote to me:

VS>> Как правильно написать Makefile на тот случай, если программа
VS>> генерирует одновременно два файла, чтобы при этом она не
VS>> запускалась дважды даже при -j2 и больше?
VS>> ==============================================================
VS>> .MAKE.JOBS= 2
VS>> all: result
VS>> foo bar: source
VS>> touch foo bar
VS>> result: foo bar
VS>> cat foo bar > result
VS>> clean:
VS>> rm -f foo bar result
VS>> ==============================================================
VS>> Вышеприведенный пример запускает touch дважды.

EG> Решение зависит от того, почему именно мы не хотим запускать touch
EG> дважды, так как лекарство не должно быть хуже болезни.

"Unfortunately this Makefile does not describe a single rule with two outputs, but rather two distinct rules that each have a single output, and that happen to use the same series of commands. In a serial build this distinction is often irrelevant and sometimes even undetectable: although GNU Make will schedule both rules to run, the second rule will never do any work because its output file will already have been updated (by the first rule). But try running this build in parallel [...]

the files are actually updated twice. In the best case, this just results in a little wasted work. In the worst case, the rules both try to update the output files at the same time, resulting in corrupted output."

(это так объясняют в https://www.cmcrossroads.com/article...puts-gnu-make)
т.е. от лишней траты вычислительных ресурсов до возможного повреждения файлов, если в них станут писать одновременно. В реальности ведь там не touch).

EG> Например, такой вариант (не тестировал):

EG> .MAKE.JOBS?= 2
EG> all: result

EG> foo: source
EG> .if ( ${.MAKE.JOBS} = 1 )
EG> touch foo bar
EG> .else
EG> make -j1 foo bar
EG> .endif

EG> bar: foo
EG> [ -f $@ ] || make -j1 foo

Вызов еще одного make изнутри Makefile мне в голову не приходил, это свежо. Но "bar: foo" конечно быть не должно, это не отражает реальной зависимости. Если например прога, обрабатывающая source, решит что foo в этот раз пересоздавать не надо, случится что-нибудь странное.

Victor Sudakov, VAS4-RIPE, VAS47-RIPN
--- GoldED+/BSD 1.1.5-b20160322-b20160322
Ответить с цитированием
  #6  
Старый 11.05.2018, 13:11
Alex Korchmar
Guest
 
Сообщений: n/a
По умолчанию Re: Makefile

Alex Korchmar написал(а) к Victor Sudakov в May 18 11:50:08 по местному времени:

From: Alex Korchmar <noreply@linux.e-moe.ru>

Victor Sudakov <Victor.Sudakov@f49.n5005.z2.fidonet.org> wrote:

AK>> То есть сперва мы специально запускаем дважды, потом пытаемся это
AK>> сломать?
VS> Почему "специально запускаем дважды"?
потому что ты зачем-то запускаешь с j2

VS> Видимо не настолько вредная, её периодически хотят, например в
людей, ниасиливших make, в современном мире столько, что жуть берет.
это не повод им уподобляться.

VS> А они (файлы foo и bar) не зависят друг от друга, они зависят только от
VS> файла source.
значит этот source нельзя обрабатывать параллельным make вообще.
Если он такой один - можно запустить вложенный, но скорее всего сегодня
один, завтра будут тыщи, поэтому прощайся с параллельной сборкой такого уродца
заранее, меньше потом возни.


> Alex

--- ifmail v.2.15dev5.4
Ответить с цитированием
  #7  
Старый 11.05.2018, 14:22
Victor Sudakov
Guest
 
Сообщений: n/a
По умолчанию Makefile

Victor Sudakov написал(а) к Alex Korchmar в May 18 16:55:52 по местному времени:

Dear Alex,

11 May 18 11:50, Alex Korchmar wrote to me:

AK>>> То есть сперва мы специально запускаем дважды, потом пытаемся
AK>>> это сломать?
VS>> Почему "специально запускаем дважды"?
AK> потому что ты зачем-то запускаешь с j2

Я указываю -j2, чтобы другие цели параллельно выполнялись. А дважды одно и то же запускает дурак-make, а не я.

VS>> Видимо не настолько вредная, её периодически хотят, например в
AK> людей, ниасиливших make, в современном мире столько, что жуть берет.
AK> это не повод им уподобляться.

Как раз по приведенным ссылкам я вижу довольно серьезные попытки осилить make. Я бы сказал, даже изнасиловать.

VS>> А они (файлы foo и bar) не зависят друг от друга, они зависят
VS>> только от файла source.
AK> значит этот source нельзя обрабатывать параллельным make вообще.

То есть потребности в колбасе нет, понятно. Хотя на самом деле можно было бы добавить некий модификатор, который сообщал бы мейку, что все перечисленные на данной строчке цели мейкаются за одно действие и параллелить их не надо. Какой-нибудь .SINGLEPASS

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

Уродец тут BSD make. Нигде не сказано, что программа, выдающая на выходе >1 файла зараз, не имеет права на существование.

BTW даже при j1 такие программы make не умеет красиво собирать, например "make -n" будет странный.

Victor Sudakov, VAS4-RIPE, VAS47-RIPN
--- GoldED+/BSD 1.1.5-b20160322-b20160322
Ответить с цитированием
  #8  
Старый 11.05.2018, 17:02
Eugene Grosbein
Guest
 
Сообщений: n/a
По умолчанию Re: Makefile

Eugene Grosbein написал(а) к Victor Sudakov в May 18 20:37:42 по местному времени:

11 мая 2018, пятница, в 12:25 NOVT, Victor Sudakov написал(а):

VS> (это так объясняют в
VS> https://www.cmcrossroads.com/article...puts-gnu-make)
VS> т.е. от лишней траты вычислительных ресурсов до возможного повреждения файлов,
VS> если в них станут писать одновременно. В реальности ведь там не touch).

Так что там в реальности-то? Если это нечто пишет в файл, не создавая
собственных блокировок против параллельной записи другой своей копией,
то эта проблема вообще не имеет отношения к make и решается стандартно,
приписыванием lockf к вызову этого нечта.

VS> Вызов еще одного make изнутри Makefile мне в голову не приходил, это свежо. Но
VS> "bar: foo" конечно быть не должно, это не отражает реальной зависимости. Если
VS> например прога, обрабатывающая source, решит что foo в этот раз пересоздавать не
VS> надо, случится что-нибудь странное.

foo bar: fileflag

fileflag: sources
lockf /tmp/touch.${.MAKE.PID} touch foo bar && echo -n > fileflag

clean:
rm -f fileflag ...

Eugene
--- slrn/1.0.2 (FreeBSD)
Ответить с цитированием
  #9  
Старый 14.05.2018, 07:11
Victor Sudakov
Guest
 
Сообщений: n/a
По умолчанию Makefile

Victor Sudakov написал(а) к Eugene Grosbein в May 18 09:36:22 по местному времени:

Dear Eugene,

11 May 18 20:37, you wrote to me:

VS>> (это так объясняют в
VS>> https://www.cmcrossroads.com/article...-outputs-gnu-m
VS>> ake) т.е. от лишней траты вычислительных ресурсов до возможного
VS>> повреждения файлов, если в них станут писать одновременно. В
VS>> реальности ведь там не touch).

EG> Так что там в реальности-то? Если это нечто пишет в файл, не создавая
EG> собственных блокировок против параллельной записи другой своей копией,
EG> то эта проблема вообще не имеет отношения к make и решается
EG> стандартно, приписыванием lockf к вызову этого нечта.

Приписывание lockf IMНO приведёт только к тому, что вторая ветка make дождется выполнения первого экземпляра нечта и таки запустит второй экземпляр.

VS>> Вызов еще одного make изнутри Makefile мне в голову не приходил,
VS>> это свежо. Но "bar: foo" конечно быть не должно, это не отражает
VS>> реальной зависимости. Если например прога, обрабатывающая source,
VS>> решит что foo в этот раз пересоздавать не надо, случится
VS>> что-нибудь странное.

EG> foo bar: fileflag

EG> fileflag: sources
EG> lockf /tmp/touch.${.MAKE.PID} touch foo bar && echo -n
EG> > fileflag

EG> clean:
EG> rm -f fileflag ...

Это некая вариация на тему "Dummy targets" из https://www.cmcrossroads.com/article...tputs-gnu-make

"We can work around this by changing the generateparser rule so that it also creates a file on disk named "generate_parser"; then on an incremental build, make will see that the file "generate_parser" is newer than parser.i and will not rebuild. But this is messy: we'll have an extra file hanging around that serves no purpose other than to work around a deficiency* *in* *the* *build* *tool, and we need to remember to manage that file along with the other outputs of the build. It should be deleted by "make clean", for example. And if somebody does something like "touch generateoutput" in between builds, that make may not be able to correctly detect that parser.c and parser.h must be rebuilt. As with the previous solution, if you only do from-scratch full builds, this solution will work fine, but with incrementals you need to be careful."


Victor Sudakov, VAS4-RIPE, VAS47-RIPN
--- GoldED+/BSD 1.1.5-b20160322-b20160322
Ответить с цитированием
  #10  
Старый 14.05.2018, 14:21
Eugene Grosbein
Guest
 
Сообщений: n/a
По умолчанию Re: Makefile

Eugene Grosbein написал(а) к Victor Sudakov в May 18 17:56:18 по местному времени:

14 мая 2018, понедельник, в 07:36 NOVT, Victor Sudakov написал(а):

EG>> Так что там в реальности-то? Если это нечто пишет в файл, не создавая
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

И в третий раз спрошу, а можно всё-таки услышать ответ?
Потому как теоретически решение от него не зависит,
но практически очень даже.

EG>> собственных блокировок против параллельной записи другой своей копией,
EG>> то эта проблема вообще не имеет отношения к make и решается
EG>> стандартно, приписыванием lockf к вызову этого нечта.
VS> Приписывание lockf IMНO приведёт только к тому, что вторая ветка make дождется
VS> выполнения первого экземпляра нечта и таки запустит второй экземпляр.

It depends. От того, возвращает ли "нечто" когда-нибуь
код ошибки EX_TEMPFAIL (75) и нет. Если нет, то проблема решается через

lockf -t0 ... && [ $? != 75 ] && while [ ! -s foo ]; do sleep 1 || break; done

то есть если lockf вернул EX_TEMPFAIL из-за блокировки,
то это не проблема и мы просто поспим до создания foo.

EG>> foo bar: fileflag
EG>> fileflag: sources
EG>> lockf /tmp/touch.${.MAKE.PID} touch foo bar && echo -n fileflag
EG>> clean:
EG>> rm -f fileflag ...
VS> Это некая вариация на тему "Dummy targets" из
VS> https://www.cmcrossroads.com/article...tputs-gnu-make

И она работает.

VS> "We can work around this by changing the generate_parser rule so that it also
VS> creates a file on disk named "generate_parser"; then on an incremental build,
VS> make will see that the file "generate_parser" is newer than parser.i and will
VS> not rebuild. But this is messy: we'll have an extra file hanging around that
VS> serves no purpose other than to work around a deficiency* *in* *the* *build
VS> tool, and we need to remember to manage that file along with the other outputs
VS> of the build. It should be deleted by "make clean", for example. And if
VS> somebody does something like "touch generate_output" in between builds, that
VS> make may not be able to correctly detect that parser.c and parser.h must be
VS> rebuilt. As with the previous solution, if you only do from-scratch full
VS> builds, this solution will work fine, but with incrementals you need to be
VS> careful."

Я не вижу никаких практических препятствий к использованию этого метода.
Более того, я активно использую его на практике и не только для сборки
чего-нибудь. У меня есть централизованное хранилище конфигов
для удалённых офисов, которые сисадмины центрального офиса могут
править локально и потом используют команду upload, которая просто
говорит cd dir && make upload и Makefile уже разбирается тупо
по timestamps, на который сервер нужно влить копию которого
локального конфига, создавая такие файл-флаги при успехе
и вливая ssh-ем обновления на конкретный сервер именно при отсутствии файл-флага.

И всё работает.

Аргумент if somebody does something like "touch generate_output"
просто смешон, а если самбоди с правами за запись в obj подменит
сгенерированные файлы там и/или подставит им фейковые mtime?

Eugene
--- slrn/1.0.2 (FreeBSD)
Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 14:39. Часовой пояс GMT +4.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc. Перевод: zCarot