Reputation: 73
I have a rule that create a file and an other one that copy it. But on running make, the prerequisites of the rule is called twice but I don't know why!
If I have a $(shell ./myscript) in prerequisite instead of the actual $(warning ...), the script is called twice!
The Makefile that reproduces the bug:
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
Actual output:
make: START
make: START
make: END
done
Expected output:
make: START
make: END
done
Why START is outputed twice? If I have a function that call a script instead of the $(warning) the script is called twice.
I have no idea... I want to keep the .SECONDEXPANSION because I don't want that the $(shell script ...) or the $(warning ...) was called when the rule is not called. I can't list all the files that will be installed in the .PRECIOUS, because I don't know since this file are generated by an external script. (like doxygen). With the .PRECIOUS: %.copy the first time START is outputed twice, but once the file exist, START is outputed once...
Thanks!
The Makefile with real 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
Upvotes: 1
Views: 122
Reputation: 57203
make -d
explains that after making target test
, it tries to make target install-copy-test
(that invokes the first pair of START/END). After that it looks for a rule with intermediate file test.copy
.
All this on assumption that you run 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
The natural fix would be to specify
.PRECIOUS: $(NAME).copy
Upvotes: 1