伪目标.PHONY

来源:互联网 发布:网络url地址是什么 编辑:程序博客网 时间:2024/05/18 06:22

这次只有一个main.cpp和一个Makefile文件。

main.cpp

[cpp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. int main()  
  5. {  
  6.     cout<<"hello world!"<<endl;  
  7.     return 0;  
  8. }  

Makefile

[plain] view plaincopy
  1. main:main.o  
  2.     g++ -o main main.o  
  3. main.o:main.cpp  
  4.     g++ -c -o main.o main.cpp  
执行make之后,目录内多出来了2个文件main.o和main,我们需要的是main,而main.o只是一个中间文件,对于我们来说并不需要,可以删除掉。

我们可以把Makefile这样写:

[plain] view plaincopy
  1. main:main.o  
  2.     g++ -o main main.o  
  3. main.o:main.cpp  
  4.     g++ -c -o main.o main.cpp  
  5. clean:  
  6.     rm *.o  
增加了一条规则,目标文件为clean,由于没有依赖的文件,也就是目标文件永远是新的,所以这条规则不会主动执行。

为了执行这条规则,我们可以这样make clean,这样就可以删除所有的.o结尾的文件。

但是当目录内没有.o结尾的文件时,这条命令将会报错,并停止往下执行。

我们把Makefile修改成这样,做个试验:

[plain] view plaincopy
  1. main:main.o  
  2.     g++ -o main main.o  
  3. main.o:main.cpp  
  4.     g++ -c -o main.o main.cpp  
  5. clean:  
  6.     rm *.o  
  7.     echo "clean obj"  
删除成功之后,将会输出clean obj。

多次执行make clean,当目录内已经没有.o结尾的文件时,将会出现下面的错误。

[plain] view plaincopy
  1. rm *.o  
  2. rm: cannot remove `*.o': No such file or directory  
  3. make: *** [clean] Error 1  
并且也没有往下执行输出clean obj,但是我们关心的不是删除的成功或失败,我们关心的是保证不存在.o结尾的文件。

但是这个Makefile中,如果不存在.o文件,竟然会报错,并且终止执行,shit。

我们可以做如下修改:

[plain] view plaincopy
  1. main:main.o  
  2.     g++ -o main main.o  
  3. main.o:main.cpp  
  4.     g++ -c -o main.o main.cpp  
  5. clean:  
  6.     -rm *.o  
也就是在rm的前面加一个减号,这样即使目录内没有.o文件,也会继续往下执行。只不过还是会有出错提示。

[plain] view plaincopy
  1. rm *.o  
  2. rm: cannot remove `*.o': No such file or directory  
  3. make: [clean] Error 1 (ignored)  
  4. echo "clean obj"  
  5. clean obj  
看到这一坨出错提示,感觉很不爽,我们在修改Makefile,如下:

[plain] view plaincopy
  1. main:main.o  
  2.     g++ -o main main.o  
  3. main.o:main.cpp  
  4.     g++ -c -o main.o main.cpp  
  5. clean:  
  6.     -rm -f *.o  
  7.     echo "clean obj"  
即在-rm和*.o之间添加-f,这样无论我们执行多少次make clean,输出结果都是:

[plain] view plaincopy
  1. rm -f *.o  
  2. echo "clean obj"  
  3. clean obj  

但是,不要以为这样就万事OK了,我们在目录内添加一个文件,文件名为clean。

我们再执行make clean,结果竟然是:

[plain] view plaincopy
  1. make: `clean' is up to date.  
由于目标clean文件没有依赖文件,并且clean文件已经存在了,所以clean这个目标文件永远是最新的,我们在clean中写的东东也永远不会执行。

怎么办,可以通过Makefile的关键字.PHONY,它显式声明一个目标文件是伪目标,执行该伪目标时,make并不关心该目标文件是否存在,只管执行。

[plain] view plaincopy
  1. main:main.o  
  2.     g++ -o main main.o  
  3. main.o:main.cpp  
  4.     g++ -c -o main.o main.cpp  
  5. .PHONY:clean  
  6. clean:  
  7.     -rm -f *.o  
  8.     echo "clean obj"  
这样,不管clean文件是否存在,make clean的时候,clean目标中的命令都会执行。

不管.o文件是否存在,make clean的时候,都不会报错。


0 0
原创粉丝点击