僞目標.PHONY

這次只有一個main.cpp和一個Makefile文件。

main.cpp

#include <iostream>
using namespace std;

int main()
{
	cout<<"hello world!"<<endl;
	return 0;
}

Makefile

main:main.o
	g++ -o main main.o
main.o:main.cpp
	g++ -c -o main.o main.cpp
執行make之後,目錄內多出來了2個文件main.o和main,我們需要的是main,而main.o只是一箇中間文件,對於我們來說並不需要,可以刪除掉。

我們可以把Makefile這樣寫:

main:main.o
	g++ -o main main.o
main.o:main.cpp
	g++ -c -o main.o main.cpp
clean:
	rm *.o
增加了一條規則,目標文件爲clean,由於沒有依賴的文件,也就是目標文件永遠是新的,所以這條規則不會主動執行。

爲了執行這條規則,我們可以這樣make clean,這樣就可以刪除所有的.o結尾的文件。

但是當目錄內沒有.o結尾的文件時,這條命令將會報錯,並停止往下執行。

我們把Makefile修改成這樣,做個試驗:

main:main.o
	g++ -o main main.o
main.o:main.cpp
	g++ -c -o main.o main.cpp
clean:
	rm *.o
	echo "clean obj"
刪除成功之後,將會輸出clean obj。

多次執行make clean,當目錄內已經沒有.o結尾的文件時,將會出現下面的錯誤。

rm *.o
rm: cannot remove `*.o': No such file or directory
make: *** [clean] Error 1
並且也沒有往下執行輸出clean obj,但是我們關心的不是刪除的成功或失敗,我們關心的是保證不存在.o結尾的文件。

但是這個Makefile中,如果不存在.o文件,竟然會報錯,並且終止執行,shit。

我們可以做如下修改:

main:main.o
	g++ -o main main.o
main.o:main.cpp
	g++ -c -o main.o main.cpp
clean:
	-rm *.o
也就是在rm的前面加一個減號,這樣即使目錄內沒有.o文件,也會繼續往下執行。只不過還是會有出錯提示。

rm *.o
rm: cannot remove `*.o': No such file or directory
make: [clean] Error 1 (ignored)
echo "clean obj"
clean obj
看到這一坨出錯提示,感覺很不爽,我們在修改Makefile,如下:

main:main.o
	g++ -o main main.o
main.o:main.cpp
	g++ -c -o main.o main.cpp
clean:
	-rm -f *.o
	echo "clean obj"
即在-rm和*.o之間添加-f,這樣無論我們執行多少次make clean,輸出結果都是:

rm -f *.o
echo "clean obj"
clean obj

但是,不要以爲這樣就萬事OK了,我們在目錄內添加一個文件,文件名爲clean。

我們再執行make clean,結果竟然是:

make: `clean' is up to date.
由於目標clean文件沒有依賴文件,並且clean文件已經存在了,所以clean這個目標文件永遠是最新的,我們在clean中寫的東東也永遠不會執行。

怎麼辦,可以通過Makefile的關鍵字.PHONY,它顯式聲明一個目標文件是僞目標,執行該僞目標時,make並不關心該目標文件是否存在,只管執行。

main:main.o
	g++ -o main main.o
main.o:main.cpp
	g++ -c -o main.o main.cpp
.PHONY:clean
clean:
	-rm -f *.o
	echo "clean obj"
這樣,不管clean文件是否存在,make clean的時候,clean目標中的命令都會執行。

不管.o文件是否存在,make clean的時候,都不會報錯。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章