Reputation:
I'm reading the make
manual and I ended up on this paragraph:
Here is how we could write a make rule for cleaning our example editor:
clean: rm edit $(objects)
In practice, we might want to write the rule in a somewhat more complicated manner to handle unanticipated situations. We would do this:
.PHONY : clean clean : -rm edit $(objects)
This prevents make from getting confused by an actual file called clean and causes it to continue in spite of errors from rm. (See Phony Targets, and Errors in Recipes.)
I understand that clean
target does not refer to a file on the filesystem but how make can getting confused if I omit the .PHONY
declaration on a target that should be declared as .PHONY
?
I would see an example that confuses the make
command.
P.S.: what does the minus symbol before rm
command represent?
Thanks.
Upvotes: 3
Views: 688
Reputation: 21435
Let's test this. Fire your terminal of choice, navigate to your directory of choice and then create a new directory (to hold the test files). I chose so-27204300
:
$ mkdir so-27204300
$ cd so-27204300
Now create a simple Makefile
without the .PHONY annotation. I'll only show the contents:
clean:
echo "Clean is executing"
Execute the make
command, you should get the following output:
$ make
echo "Clean is executing"
Clean is executing
Now, create a clean
file (touch clean
) and execute make
again. You'll get
$ make
make: `clean' is up to date.
because there is a file clean
newer than the output of the target clean
. Add .PHONY clean
to the Makefile
so it will read
.PHONY: clean
clean:
echo "Clean is executing"
Now, even with the file clean
in your directory, make
will execute the target
$ make
echo "Clean is executing"
Clean is executing
Regarding your PS: change this Makefile
so that it reads:
.PHONY: clean
clean:
rm test
echo "Done"
As you see, there's no -
there but also there is no test
file in the current directory. Running make
will give you
$ make
rm test
rm: cannot remove ‘test’: No such file or directory
make: *** [clean] Error 1
And no output from echo
. If the clean
target was a prerequisite to another target then because of this error the other target would not have been built either.
Adding a -
so that the Makefile
reads:
.PHONY: clean
clean:
-rm test
echo "Done"
solves this problem:
$ make
rm test
rm: cannot remove ‘test’: No such file or directory
make: [clean] Error 1 (ignored)
echo "Done"
Done
For rm
you can also use -f
to let it stop complaining on errors. But there are other commands which don't have a silencer of errors argument.
If you want to hide the printing of command being executed you can use @
instead of -
.
Upvotes: 3