Странное поведение с правилом - PullRequest
1 голос
/ 09 октября 2019

У меня есть правило, которое создает файл, и другое, которое копирует его. Но при запуске make предварительные условия правила вызываются дважды, но я не знаю почему!

Если у меня есть $ (shell ./myscript) в предварительных условиях вместо фактического $ (предупреждение ... ), скрипт вызывается дважды!

Makefile, который воспроизводит ошибку:

NAME := test

$(NAME):
    @touch $@

install-$(NAME): $(NAME) install-copy-$(NAME)

.PHONY: install-$(NAME)
.PRECIOUS: %.copy

.SECONDEXPANSION:

%.copy: $$*
    @cp $< $@

install-copy-%: $$(warning START) $$*.copy $$(warning END)
    @echo done

Фактический вывод:

make: START
make: START
make: END
done

Ожидаемый результат:

make: START
make: END
done

Почему START рассчитывается дважды? Если у меня есть функция, которая вызывает скрипт вместо $ (предупреждение), скрипт вызывается дважды.

Понятия не имею ... Я хочу сохранить .SECONDEXPANSION, потому что я не хочу, чтобы$ (сценарий оболочки ...) или $ (предупреждение ...) вызывается, когда правило не вызывается. Я не могу перечислить все файлы, которые будут установлены в .PRECIOUS, потому что я не знаю, так как этот файл генерируется внешним скриптом. (как Doxygen). С .PRECIOUS:% .copy первый раз START выводится дважды, но как только файл существует, START выводится один раз ...

Спасибо!

Makefile с реальнымcase:

NAME := test
INSTALL_DIR := saved

# generate the documentation into $$*/
generateDoc-%:
    touch $*/$(shell head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')

install-$(NAME): generateDoc-$(NAME) install-doc-$(NAME)

.PHONY: install-$(NAME)
.PRECIOUS: $(INSTALL_DIR)/%

.SECONDEXPANSION:

$(INSTALL_DIR)/%: $$(NAME)/$$*
    cp $< $@

install-doc-%: $$(warning START) $$(subst $$*,$$(INSTALL_DIR),$$(shell find $$* -type f)) $$(warning END)
    @echo done

1 Ответ

1 голос
/ 10 октября 2019

make -d объясняет, что после создания цели test она пытается сделать цель install-copy-test (которая вызывает первую пару START / END). После этого он ищет правило с промежуточным файлом test.copy.

. Все это при условии, что вы запустите make install-test

> make install-test -n
touch test
make: START
make: END
make: START
make: END
cp test test.copy
done
rm test.copy

. Естественным решением было бы указать

.PRECIOUS: $(NAME).copy
...