拾遺是自己平時查閱另一個資料,然後引申出來的知識了解,答應自己,寫完這個趕緊去睡覺咯,明早還有大物課
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:
[email protected]:~/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