I have the following Makefile:
all: generate print # <-- doesn't work
date:
date > date.txt
ls:
ls -la > ls.txt
generate: ls date
print: *.txt
cat $^
clean:
rm *.txt
The targets date and ls generate a file each, the target print, prints them out.
How do I write the target all, so that it first generates the files and then prints it?
Just add the pipe symbol:
all: | generate print
From the make manual:
Order-only prerequisites can be specified by placing a pipe symbol (
|
) in the prerequisites list: any prerequisites to the left of the pipe symbol are normal; any prerequisites to the right are order-only:targets : normal-prerequisites | order-only-prerequisites
The dependancy hierarchy of the rules you want is all -> print -> generate. 'print' should be dependant on 'generate'.
The Makefile you have is interesting. On first pass it generates the .txt files using { all -> generate -> ls, date } hierarchy but the print fails. On second pass if you don't do clean it works.
The 'print' rule you have is a valid rule. But doesn't allow make to know that you need to do the 'generate' actions before doing the 'print'.
You could EXplicitly make a print rule which says it is dependant on generating date.txt and ls.txt. Try change your 'all' and 'print' rules like this . . .
EDIT: SORRY! First Answer I gave doesn't work. Tested it. This works.
all: print # <- just print target here as you don't want generate to happen after print
.
print: generate ls.txt date.txt
cat $^
Make could decide to do print action first and the generate action afterwards if print is not made dependant on the files explicitly or generate.
This works but we get an error as the cat of non existant file generate doesn't work.
Taking this a bit further . . . Get rid of the generate rule. And I think the date and ls rule would be better if they explicitly detailed what file they generated, i.e.
all: print
date.txt:
date > date.txt
ls.txt:
ls -la > ls.txt
print: ls.txt date.txt
cat $^
*.txt. If you want to operate on multiple files with same extension then you can do different things e.g. put the list of files in a make variable. You can have a make rule to calculate this list of files (using shell cmd in make). But that make rule cannot be dependant on the files already existing if it is the thing that is generating them.
The make manual gives a rule very close to your original print rule - using wildcard in rule prerequisites. http://www.gnu.org/software/make/manual/make.html#Wildcard-Examples
Make has quite a simple hierarchy of dependancies. Make will follow dependancies in order. Getting your head around the sequence a makefile will follow can be tricky but it is actually quite simple enough so well worth while working on understanding it.
It is a common problem for makefiles for some part of make system to be missing a dependancy on another. Often build systems will get away with this but sometimes it can cause weirdness (e.g. object files being compiled after being linked in).
The make manual has a good introduction. http://www.gnu.org/software/make/manual/make.html#Introduction
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With