`

Makefile里PHONY的介绍

 
阅读更多

Phony Targets

PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字。有两种理由需要使用PHONY 目标:避免和同名文件冲突,改善性能。

如果编写一个规则,并不产生目标文件,则其命令在每次make 该目标时都执行。例如:
  clean:
  rm *.o temp
因为"rm"命令并不产生"clean"文件,则每次执行"make clean"的时候,该命令都会执行。如果目录中出现了"clean"文件,则规则失效了:没有依赖文件,文件"clean"始终是最新的,命令永远不会 执行;为避免这个问题,可使用".PHONY"指明该目标。如:
  .PHONY : clean
  这样执行"make clean"会无视"clean"文件存在与否。

已知phony 目标并非是由其它文件生成的实际文件,make 会跳过隐含规则搜索。这就是声明phony 目标会改善性能的原因,即使你并不担心实际文件存在与否。
  完整的例子如下:
  .PHONY : clean
  clean :
  rm *.o temp

phony 目标可以有依赖关系。当一个目录中有多个程序,将其放在一个makefile 中会更方便。因为缺省目标是makefile 中的第一个目标,通常将这个phony 目标叫做"all",其依赖文件为各个程序:
  all : prog1 prog2 prog3
  .PHONY : all
  prog1 : prog1.o utils.o
   cc -o prog1 prog1.o utils.o
  prog2 : prog2.o
   cc -o prog2 prog2.o
  prog3 : prog3.o sort.o utils.o
   cc -o prog3 prog3.o sort.o utils.o

假设你的一个项目最后需要产生两个可执行文件。你的主要目标 是产生两个可执行文件,但这两个文件是相互独立的——如果一 个文件需要重建,并不影响另一个。你可以使用“假象目的”来 达到这种效果。一个假象目的跟一个正常的目的几乎是一样的, 只是这个目的文件是不存在的。因此, make 总是会假设它需要 被生成,当把它的依赖文件更新后,就会执行它的规则里的命令 行。

如果在我们的 makefile 开始处输入:

all : exec1 exec2

其中 exec1 和 exec2 是我们做为目的的两个可执行文件。 make 把这个 'all' 做为它的主要目的,每次执行时都会尝试把 'all' 更新。但既然这行规则里没有哪个命令来作用在一个叫 'all' 的 实际文件(事实上 all 并不会在磁碟上实际产生),所以这个规 则并不真的改变 'all' 的状态。可既然这个文件并不存在,所以 make 会尝试更新 all 规则,因此就检查它的依靠 exec1, exec2 是否需要更新,如果需要,就把它们更新,从而达到我们的目的。

假象目的也可以用来描述一组非预设的动作。例如,你想把所有由 make 产生的文件删除,你可以在 makefile 里设立这样一个规则:

veryclean :
rm *.o
rm myprog

前提是没有其它的规则依靠这个 'veryclean' 目的,它将永远 不会被执行。但是,如果你明确的使用命令 'make veryclean' , make 会把这个目的做为它的主要目标,执行那些 rm 命令。

如果你的磁碟上存在一个叫 veryclean 文件,会发生什么事?这 时因为在这个规则里没有任何依靠文件,所以这个目的文件一定是 最新的了(所有的依靠文件都已经是最新的了),所以既使用户明 确命令 make 重新产生它,也不会有任何事情发生。解决方法是标 明所有的假象目的(用 .PHONY),这就告诉 make 不用检查它们 是否存在于磁碟上,也不用查找任何隐含规则,直接假设指定的目 的需要被更新。在 makefile 里加入下面这行包含上面规则的规则:

.PHONY : veryclean

就可以了。注意,这是一个特殊的 make 规则,make 知道 .PHONY 是一个特殊目的,当然你可以在它的依靠里加入你想用的任何假象 目的,而 make 知道它们都是假象目的。

分享到:
评论

相关推荐

    linux 实用makefile例子

    .PHONY : all deps objs clean rebuild all: $(EXECUTABLE) $(CXX) $(CXXFLAGS) $(INCLUDEPATH) $(LIBS) $(LIBPATH) $(addprefix $(OBJSPATH),$(OBJS)) \ -o $(EXECUTABLEPATH)$(EXECUTABLE) deps: $(addprefix $...

    linux应用开发中makefile源码

    在Linux系统中,Makefile是一种文本文件,用于定义和管理软件项目的编译和构建过程。Makefile使用make命令来根据定义的规则和依赖关系自动化地进行编译和构建。 Makefile通常包含以下内容: 1. 变量(Variables):...

    make与Makefile

    1.2.Makefile介绍 3 1.3.规则简介 4 1.4.make工作原理 4 1.5.使用变量 5 1.6.简化命令 6 1.7.另一种风格 6 1.8 清理 7 2 Makefile 7 2.1 makefile名字 7 2.2包含 8 2.3 ‘MAKEFILE’变量 8 2.4 如何重新生成makefile...

    万能makefile写法详解,一步一步写一个实用的makefile

    可见,只要把这些行挪到makefile里,就能自动定义main.c的依赖是哪些文件了,做法是把命令的输出重定向到.d文件里:gcc -MM main.c > main.d,再把这个.d文件include到makefile里。 如何include当前目录每个.c生成的...

    android make 介绍

    android make 介绍 Make 文件说明 整个 Build 系统的入口文件是源码树根目录下名称为“Makefile”的文件,当在源代码根目录上调用 make 命令 时,make 命令首先将读取该文件。 Makefile 文件的内容只有一行:...

    GNU Make 使用手冊(繁體版)

    1 make概述 1.1 怎樣閱讀本手冊 1.2 問題和BUG 2 Makefile檔案介紹 2.1 規則的格式 2.2一個簡單的Makefile檔案 2.3mke處理Makefile檔案的過程 2.4使用變數簡化Makefile檔案 2.5讓make推斷...

    ckati与ninja构建demo

    1.编译出ckati工具 ...# make -j8 # sudo cp ckati /usr/local/bin 2.ckati与ninja构建过程 注意:Android.mk本质上就是Makefile. .内容一致(注意:ckati....PHONY:clean all:hello hello :hello.c $(CC) -o $@ $< c

    【Linux】meke实现自动化的一个例子

    文件夹里边放了一个名为makefile的文件; makefile里边的内容如下: .ONESKELL: .PHONY: redd redd:  mkdir test;  cd test;  npm init; 其中 “.ONESKELL:”的意思是允许命令换行 “.PHONY: redd”的意思是声明...

    嵌入式linux c语言实现MDIO控制,修改交叉编译,实现MDIO指令自定义

    Makefile arm_cross_gcc = /home/fmsh/work/FMQL-Linux-SDK/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc objects = mdio.o mdio: $(objects) $(arm_cross_gcc) -o mdio $...

    contest:因为我们都有很多空闲时间;)

    每个解决方案还必须提供一个具有以下三个目的的 makefile: 构建(作为第一个目标,默认情况下):准备/构建解决方案 运行:启动解决方案 clean:删除解决方案生成的所有文件 例子 compile : gcc -o solution ...

    erl-mk:更快地构建Erlang应用

    包括在您的Makefile中: all : app | erl.mk erl.mk : curl -fsSLo $@ ' https://raw.github.com/fenollp/erl-mk/master/erl.mk ' || rm $@ -include erl.mk # Your targets after this line. # # Example: test...

    config-commitlint:在flagbit上使用Commitlint配置

    配置委员会 在flagbit上使用Commitlint配置 如何在我的项目中使用它? 在项目的根目录中创建一个名为commitlint.config.js的新文件,包括以下内容....PHONY : lint lint : commitlint -g index.js --from= $$( git re

    oop1_2021

    2021年第4学期有用的实用程序: Makefile : CXX = g++EXEC = mainCXXFLAGS = -std=c++14 -Wall -pedanticSRC = $( wildcard * .cpp)OBJS = $( SRC:.cpp=.o )all : $( EXEC ) run$( EXEC ) : $( OBJS )$( CXX ) $^ ...

    毕业设计论坛源码-ideas:收集要完成的想法

    毕业设计论坛源码想法 Docker 监控 之前做过这个,但是没有写步骤让别人复制。 此外,我还想进行一些改进,例如生成关于指标(CPU ...注意:在非构建目标上使用.PHONY 。 objects = foo.o bar.o all: $(ob

    linux驱动学习去开发入门

    .PHONY: modules modules_install clean 说实话,以上是我参考了《Linux设备驱动程序(第3版)》的Makefile源码修改得来的。我对Makefile不是很了解,是该好好学习学习了! 然后就是make modules 、 make modules_...

Global site tag (gtag.js) - Google Analytics