Файлы, похожие на базы данных, как цели и предпосылки в Makefile - PullRequest
0 голосов
/ 25 октября 2018

Скажем, у меня есть простой Makefile.

a1: some_script b
    some_command $< b
a2: some_other_script b
    some_command $< b
b: c
    touch $@
c:
    touch $@

Где b - это файл, похожий на базу данных, который требуется для создания a1 и a2.Однако каждый раз при обращении к b (даже если не изменяется) дата изменения изменяется.Следовательно, каждый раз, когда выполняется правило для a2, Make считает, что a1 необходимо переделать, потому что использовалась база данных b (даже если c не изменился и b остался прежним).Я хочу обновить только a1 и a2, если c новее (и, следовательно, b нуждается в фактической перекомпиляции).

Я мог бы просто иметь a1 и a2 зависит от c напрямую, но это искажает истинный рабочий процесс.

Я не хочу удалять b, поэтому использование его в качестве промежуточного файла не будет работать.

У меня естьтакже пытался включить b как зависимость только для заказа, но a1 и a2 никогда не будут пересозданы, если их не принудить.

Примечания. Makefile предназначен для автоматизации выполнения сценариев и отслеживания зависимостей для исследовательского проекта (а не программного проекта).Возможно, Make не подходит для этого.Файлы в виде базы данных - это GeoPackages.

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

Возможно, вы могли бы просто предотвратить бесполезные изменения отметки времени b:

a1: some_script b
    touch -r b .b.a1
    some_command $< b
    touch -r .b.a1 b && rm .b.a1

a2: some_other_script b
    touch -r b .b.a2
    some_command $< b
    touch -r .b.a2 b && rm .b.a2

Но будьте осторожны: если вы запускаете make в параллельном режиме (make -j), a1 и a2 рецепты могут быть запущены параллельно с потенциальными условиями гонки.Поэтому, вероятно, лучше сериализовать их с .NOTPARALLEL: или с использованием flock в рецептах.

0 голосов
/ 01 ноября 2018

Я думаю, что " предварительное условие только для заказа " может помочь:

a1: some_script | b
    some_command $< b
a2: some_other_script | b
    some_command $< b
b: c
    touch $@
c:
    touch $@
0 голосов
/ 25 октября 2018

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

a1: some_script .buildc
        some_command $< b

a2: some_other_script .buildc
        some_command $< b

.buildc: c
        command to update b
        touch $@

c:
        touch $@

Это будет выполняться command to update b только если c новее, чем .buildc, который устанавливается каждый раз, когда эта команда вызывается, а не когда используется b.

...