Reputation: 35
I have a script that, when run, generates a file. I want to create a Makefile to run the script to generate the file if the generated file does not exist or if the script changes.
Here's a simplified version. Let's say I have an executable script gen_test.sh
like this:
#!/bin/sh
echo "This is a generated file" > genfile.foo
And a Makefile like this:
#
# Test Makefile
#
GEN_SCRIPT = $(CURDIR)/gen_test.sh
GEN_FILE = $(CURDIR)/genfile.foo
$(GEN_FILE): $(GEN_SCRIPT)
$(shell $(GEN_SCRIPT))
.PHONY: clean
clean:
$(RM) $(GEN_FILE)
When I run make
, I see the following output:
make: '/workspace/sw/bhshelto/temp/makefile_test/genfile.foo' is up to date.
but genfile.foo
does in fact get generated.
What's going on here? Why do I see the "is up to date" message, and how do I get rid of it?
Thanks!
Upvotes: 0
Views: 1064
Reputation: 17420
When I run
make
, I see the following output:make: '/workspace/sw/bhshelto/temp/makefile_test/genfile.foo' is up to date.
but
genfile.foo
does in fact get generated.
As user657267 has suggested: remove the $(shell)
from the recipe body.
Assuming that the gen_test.sh
doesn't produce any output (or output only on stderr), the explanation for the behavior is rather simple:
The make
detects that the $(GEN_FILE)
needs to be rebuild and goes to invoke the rule.
Before the command invocation, make
performs the expansion of the variables inside the commands. Due to the (unnecessary) $(shell)
, the $(GEN_SCRIPT)
gets invoked already during this expansion.
The $(GEN_SCRIPT)
does it work, but produces no output, thus $(shell $(GEN_SCRIPT))
is expanded to an empty string.
Make sees that the command is empty, and thus there is no command to run.
The make
then again checks the files (in case the variable expansion has side-effects) and sees that the target is up-to-date. Yet, since the expanded command is empty, the make
prints its generic is up to date
message.
Upvotes: 1