拾遗是自己平时查阅另一个资料,然后引申出来的知识了解,答应自己,写完这个赶紧去睡觉咯,明早还有大物课
PHONY的用法以及意义:以下内容来自于stackoverflow上面的一个问题的翻译以及对一些博客的总结和自己的一些理解https://stackoverflow.com/questions/2145590/what-is-the-purpose-of-phony-in-a-makefile
这是大牛的原回答,我把大概意思精简一下:
By default, Makefile targets are "file targets" - they are used to build files from other files. Make assumes its target is a file, and this makes writing Makefiles relatively easy:
foo: bar
create_one_from_the_other foo bar
However, sometimes you want your Makefile to run commands that do not represent physical files in the file system. Good examples for this are the common targets "clean" and "all". Chances are this isn't the case, but you may potentially have a file named clean
in your main directory. In such a case Make will be confused because by default the clean
target would be associated with this file and Make will only run it when the file doesn't appear to be up-to-date with regards to its dependencies.
These special targets are called phony and you can explicitly tell Make they're not associated with files, e.g.:
.PHONY: clean
clean:
rm -rf *.o
Now make clean
will run as expected even if you do have a file named clean
.
In terms of Make, a phony target is simply a target that is always out-of-date, so whenever you ask make <phony_target>
, it will run, independent from the state of the file system. Some common make
targets that are often phony are: all
, install
, clean
, distclean
, TAGS
, info
, check
.
就是说makefile认为你写一个命令,比如说是clean,是一个目标文件,这样Make这个命令会认为clean是一个文件,这样让编写makefile更加的容易,但是有个问题,如果说和你的makefile同级目录下还有一个clean的文件,那么你去make clean就会失败,这时候你就需要用PHONY,说明这个是一个假的目标文件,这样你的make clean 就会成功执行,否则就会弹出 makefile is
up to date,你需要使用PHONY 的场合还有:all
, install
, clean
, distclean
, TAGS
, info
, check
.这些时候
a phony target is simply a target that is always out-of-date 这句话很经典啊,一个phony的目标文件就像是一个过时的目标文件
有个人提出了一个问题:So, if a: b
, b: c
, c: ph
where ph
is .PHONY
, you ask for a
, and b
is up-to-date, your comment implies that ph
will be run. In fact, none of a
, b
, c
can ever be up-to-date, actually.
这个东西我会这周周末的时候试一下,因为要准备概率论的考试,累的一匹。。。
有这样一个例子大家可以参考:
NOTE: The make tool reads the makefile and checks the modification time-stamps of the files at both the side of ':' symbol in a rule.
Example
In a directory 'test' following files are present:
prerit@vvdn105:~/test$ ls
hello hello.c makefile
In makefile a rule is defined as follows:
hello:hello.c
cc hello.c -o hello
Now assume that file 'hello' is a text file containing some data, which was created after 'hello.c' file. So the modification (or creation) time-stamp of 'hello' will be newer than that of the 'hello.c'. So when we will invoke 'make hello' from command line, it will print as:(假设hello这个file包含一些数据,)
make: `hello' is up to date.
Now access the 'hello.c' file and put some white spaces in it, which doesn't affect the code syntax or logic and then save and quit. Now the modification time-stamp of hello.c is newer than that of the 'hello'. Now if you invoke 'make hello', it will execute the commands as:(这段和上面那段的大概意思就是你本来有一个hello的文本文件,但是你gcc之后生成了一个hello的可执行文件,这个就会覆盖原本的hello文本文件)
cc hello.c -o hello
And the file 'hello' (text file) will be overwritten with a new binary file 'hello' (result of above compilation command).
If we use .PHONY in makefile as follow:
.PHONY:hello
hello:hello.c
cc hello.c -o hello
and then invoke 'make hello', it will ignore if any file present in the pwd named 'hello' and execute the command every time.
Now suppose if no dependencies of target is there in makefile:(假设他没有依赖文件)
hello:
cc hello.c -o hello
and 'hello' file is already present in the pwd 'test', then 'make hello' will always show as:
make: `hello' is up to date.
还有一个例子,我会在周末的时候一并翻译,另外一个关于PHONY用法的范例:
There's also one important tricky treat of ".PHONY" - when a physical target depends on phony target that depends on another physical target:
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2
You'd simply expect that if you updated TARGET2, then TARGET1 should be considered stale against TARGET1, so TARGET1 should be rebuild. And it really works this way.
The tricky part is when TARGET2 isn't stale against TARGET1 - in which case you should expect that TARGET1 shouldn't be rebuild.
This surprisingly doesn't work because: the phony target was run anyway (as phony targets normally do), which means that the phony target was considered updated. And because of that TARGET1 is considered stale against the phony target.
Consider:
all: fileall
fileall: file2 filefwd
echo file2 file1 >fileall
file2: file2.src
echo file2.src >file2
file1: file1.src
echo file1.src >file1
echo file1.src >>file1
.PHONY: filefwd
.PHONY: filefwd2
filefwd: filefwd2
filefwd2: file1
@echo "Produced target file1"
prepare:
echo "Some text 1" >> file1.src
echo "Some text 2" >> file2.src
You can play around with this:
- first do 'make prepare' to prepare the "source files"
- play around with that by touching particular files to see them updated
You can see that fileall depends on file1 indirectly through a phony target - but it always gets rebuilt due to this dependency. If you change the dependency in fileall
from filefwd
to file
, now fileall
does not get rebuilt every time, but only when any of dependent targets is stale against it as a file.
如果你想了解更多的关于PHONY的知识还是得浏览官方文档,周末我会浏览官方文档: https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html