phtyon语法

拾遗是自己平时查阅另一个资料,然后引申出来的知识了解,答应自己,写完这个赶紧去睡觉咯,明早还有大物课 PHONY的用法以及意义:以下内容来自于stackoverflow上面的一个问题的翻译以及对一些博客的总结和自己的一些理解https://stackoverflow

 

 

拾遗是自己平时查阅另一个资料,然后引申出来的知识了解,答应自己,写完这个赶紧去睡觉咯,明早还有大物课

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: allinstallcleandistcleanTAGSinfocheck.

就是说makefile认为你写一个命令,比如说是clean,是一个目标文件,这样Make这个命令会认为clean是一个文件,这样让编写makefile更加的容易,但是有个问题,如果说和你的makefile同级目录下还有一个clean的文件,那么你去make clean就会失败,这时候你就需要用PHONY,说明这个是一个假的目标文件,这样你的make clean 就会成功执行,否则就会弹出 makefile is

 up to date,你需要使用PHONY 的场合还有:allinstallcleandistcleanTAGSinfocheck.这些时候

a phony target is simply a target that is always out-of-date 这句话很经典啊,一个phony的目标文件就像是一个过时的目标文件

有个人提出了一个问题:So, if a: bb: cc: 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 abc 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

知秋君
上一篇 2024-07-10 12:48
下一篇 2024-07-10 12:12

相关推荐