makefile中的.PHONY和all的作用

makefile中的.PHONY和all的作用PHONY 伪目标 伪目标是这样一个目标 它不代表一个真正的文件名 在执行 make 时可以指定这个目标来执行所在规则定义的命令 有时也可以将一个伪目标称为标签 伪目标通过 PHONY 来指明 PHONY 定义伪目标的命令一定会被执行 下面尝试分析这种优点的妙处 1 如果我们指定的目标不是创建目标文件 而是使用 makefile 执行一些特定的命令 例如 clean rm o

.PHONY(伪目标)

伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行所在规则定义的命令,有时也可以将一个伪目标称为标签。伪目标通过PHONY来指明。

 PHONY定义伪目标的命令一定会被执行,下面尝试分析这种优点的妙处。 

1、如果我们指定的目标不是创建目标文件,而是使用makefile执行一些特定的命令,例如:

clean: rm *.o temp 

我们希望,只要输入”make clean“后,”rm *.o temp“命令就会执行。但是,当当前目录中存在一个和指定目标重名的文件时,例如clean文件,结果就不是我们想要的了。输入”make clean“后,“rm *.o temp” 命令一定不会被执行。

解决的办法:将目标clean定义成伪目标就成了 无论当前目录下是否存在“clean”这个文件,输入“make clean”后,“rm *.o temp”命令都会被执行。

注意:这种做法的带来的好处还不止此,它同时提高了make的执行效率,因为将clean定义成伪目标后,make的执行程序不会试图寻找clean的隐含规则。

2、PHONY可以确保源文件(*.c *.h)修改后,对应的目标文件会被重建。

all

main1.c:

#include int main(void) { 
    printf("main1\n"); } 

main2.c:

#include int main(void) { printf("main2\n"); } 

【分析】:这里需要生成两个可执行文件main1和main2(两个目标)。由于makefile只能有一个目标,所以可以构造一个没有规则的终极目标all,并以这两个可执行文件作为依赖。如下:

makefile: all:main1 main2 main1: main1.c gcc main1.c -o main1 main2: main2.c gcc main2.c -o main2 

很多时候我们在执行make时会产生许多过程文件,比如将上面的makefile改为:

makefile:

all:main1 main2 main1: main1.c gcc main1.c -o main1 main2: main2.o gcc main2.o -o main2 main2.o: main2.c gcc -c main2.c 

这样就会生成一个我们不需要的过程文件main2.o。

如果希望将生成的过程文件删掉,根据前面再增加一个目标clean:

all:main1 main2 clean main1: main1.c gcc main1.c -o main1 main2: main2.o gcc main2.o -o main2 main2.o: main2.c gcc -c main2.c clean: rm -f main2.o 

但是当我们make之后main2.o仍然存在,怎么回事呢makefile中的all和.PHONY的作用

原来这里的目标clean没有任何依赖,make执行时认为这已经到“根上”了(就是认为磁盘上有clean,就像main2.c),将其忽略(尽管它有规则)。

关键字.PHONY可以解决这问题,告诉make该目标是“假的”(磁盘上其实没有clean),这时make为生成这个目标就会将其规则执行一次。.PHONY修饰的目标就是只有规则没有依赖。

加上一句.PHONY:clean即可:

all:main1 main2 clean main1: main1.c gcc main1.c -o main1 main2: main2.o gcc main2.o -o main2 main2.o: main2.c gcc -c main2.c .PHONY:clean clean: rm -f main2.o 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/211325.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午10:41
下一篇 2026年3月18日 下午10:42


相关推荐

  • 123213

    12321321321213sdasdsadddddddddddddddddddddddddd

    2022年4月30日
    62
  • Openclaw 接入EvoMap

    Openclaw 接入EvoMap

    2026年3月15日
    4
  • VIF检验相关性「建议收藏」

    VIF检验相关性「建议收藏」VIF可以用来度量多重共线性问题,VIFj=11−Rj2\quad\mathrm{VIF}_{j}=\frac{1}{1-R_{j}^{2}}VIFj​=1−Rj2​1​式子中,Rj2R_{j}^{2}Rj2​是第jjj个变量在所有变量上回归时的确定系数。如果VIF过大(比如大于5或10),则意味着存在多重共线性问题。#数据df=pd.read_excel(io=’数据.xlsx’,sheet_name=0,usecols=range(1,5))#务必注意:一定要加上常数项,#如果没

    2022年4月28日
    142
  • 内存调试MEMWATCH

    内存调试MEMWATCH
    内存调试-MEMWATCH
     
    MEMWATCH由JohanLindh编写,是一个开放源代码C语言内存错误检测工具,您可以自己下载它(请参阅本文后面部分的参考资料)。只要在代码中添加一个头文件并在gcc语句中定义了MEMWATCH之后,您就可以跟踪程序中的内存泄漏和错误了。MEMWATCH支持ANSIC,它提供结果日志纪录,能检测双重释放(double-free)、错误释放(erroneousfree)、没有释放的内存(unfreedmemo

    2022年7月15日
    17
  • sendfile函数–零拷贝

    sendfile函数–零拷贝零拷贝:零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除通信数据在存储器之间不必要的中间拷贝过程,有效地提高通信效率,是设计高速接口通道、实现高速服务器和路由器的关键技术之一。sendfile#includessize_tsendfile(intout_fd,intin_fd,off_t*offset,size_tcount);参数特别注意

    2022年5月24日
    64
  • 关于函数模板描述错误的是(链接格式错误怎么解决)

    状况1:函数是通用基本函数,故没有放到任何类中,为全局的。声明与实现分别放到.h和.cpp中,编译报:链接错 1:不使用模板函数,用重载 ok2:使用模板函数,但是将定义也一同放到.h中,ok   状况2:在a.h文件中定义的都是模板函数,添加普通函数,编译连接出错,重定义1:将新函数也定义为模板函数2:将新函数定义到其它的.h文件中 3:

    2022年4月15日
    143

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号