In this Makefile...
all: piped.mk
ifeq ($(PIPED),1)
@echo Output of make is piped
else
@echo Output of make is NOT piped
endif
piped.mk:
[ -t 1 ] && PIPED=0 || PIPED=1 ; echo "PIPED=$${PIPED}" > piped.mk
.PHONY: piped.mk all
include piped.mk
...I would expect the following:
- The first rule,
all
, says it depends on the filepiped.mk
. - The file
piped.mk
is generated by asking the shell whether the terminal's stdout is a TTY or not - The file
piped.mk
isinclude
d at the end; in theory therefore this should triggermake
s "remaking" logic (see section 3.5 in themake
manual) - To force the creation of
piped.mk
(since it is not supposed to depend on files, but on the waymake
was invoked), it is also marked as a .PHONY target - one that should be remade no matter what.
If these assumptions are correct, I don't understand this result:
$ make
[ -t 1 ] && PIPED=0 || PIPED=1 ; echo "PIPED=${PIPED}" > piped.mk
Output of make is NOT piped
$ cat piped.mk
PIPED=0
$ make | more
[ -t 1 ] && PIPED=0 || PIPED=1 ; echo "PIPED=${PIPED}" > piped.mk
Output of make is NOT piped
$ cat piped.mk
PIPED=1
It appears that file piped.mk
is always remade, as intended - and it indeed contains the intended information (whether the standard output is piped or not). The Makefile however, seems to ignore the value of PIPED - it always reports "NOT piped"; as if piped.mk
is not re-included after its regeneration...
UPDATE
Traditionally, the prototypical example of automatically generated Makefile
parts is the generation of the C file dependencies - in which case all examples I've seen end up using include
at the bottom of the Makefile. However, maybe this approach only works for the generation of dependencies, and does not work for the assignment of Makefile variables...
To check if this was the reason, I attempted to move the include
up to the top...
$ cat Makefile
include piped.mk
all: ...
...which caused a nasty "delay" effect:
$ rm -f piped.mk
$ make | more
[ -t 1 ] && PIPED=0 || PIPED=1 ; echo "PIPED=${PIPED}" > piped.mk
Output of make is NOT piped
$ make | more
[ -t 1 ] && PIPED=0 || PIPED=1 ; echo "PIPED=${PIPED}" > piped.mk
Output of make is piped
Basically, the inclusion does happen - but it happens BEFORE the piped.mk
generation. It therefore uses the "old" value of the definition of PIPED, not the new one that was just placed inside piped.mk
upon execution. Maybe the re-inclusion of piped.mk
is only allowed to update dependency rules and not variable definitions?
So, my question:
Is it possible to auto-generate a part of a Makefile that contains variable definitions, and include it within the same Makefile invocation?
That is, without a separate $(MAKE)
invocation - which is the only way I have found so far to make it work:
all:
@[ -t 1 ] && PIPED=0 || PIPED=1 ; \
$(MAKE) binary "PIPED=$${PIPED}"
binary:
ifeq ($(PIPED),1)
@echo Output of make is piped
else
@echo Output of make is NOT piped
endif
.PHONY: all binary
Thanks for any suggestions.