伪目标.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的时候,都不会报错。


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