第三载:makefile中的伪目标

    在前边的两个章节中,我们提到了makefile中的目标,并且知道这个目标存在且依赖没有更新,make就不再编译程序。
一般在默认的情况下
    - make 认为目标对应着一个文件(可执行程序、so库等等)
    - 比较目标文件和依赖的新旧关系,决定是否执行命令
    - make以文件处理作为第一优先级

clean :
    rm *.o hello.out

在上边的一个简单的makefile文件中,当我们执行make clean时,就会删除.o、hello.out文件,因为clean目标被make认为是文件,当目录下有一个文件叫clean时,make clean 下的命令便不会执行。所以我们希望clean 不对应文件,仅仅对应一个类似标签这样的东西。

    解决方案:引入伪目标
 
   - makefile中的伪目标通过 .PHONY关键字声明
    - 伪目标不对应任何实际的文件,其下的命令总是执行
    伪目标需要先声明后使用,声明语法为 .PHONY : clean
    伪目标本质为.PHONY目标的依赖

.PHONY : clean  #声明clean为伪目标
clean : 
    rm *.o hello.out

此时执行make clean,其他的命令总是被执行,不关注依赖是否有更新

一、伪目标的使用技巧1
    我们在编译程序的时候,希望make包含的功能有删除现有文件、编译、重编译(先删除后编译),这时候可以使用伪目标,makefile文件如下

.PHONY clean rebuild all  #声明3个伪目标

rebuild : clean all  #伪目标 rebuild 依赖与伪目标 clean 与 all

all : main.o func.o
    gcc -o hello.out main.o func.o

main.o : main.c
    gcc -o main.o -c main.c

func.o : func.c
        gcc -o func.o -c func.c

clean :
    rm *.o hello.out

在如上的makefile中,我们定义了三个伪目标 clean、 rebuild、 all,并且将rebuild的伪目标依赖设为clean、all,所以当执行make rebuild时,就会先执行clean all 伪目标下的命令,这有点类似函数调用。
调用原理:当一个伪目标的依赖包含伪目标时,伪目标所定义的命令总是会被执行
执行make rebuild的结果如下(每次都是强制重编)

/home/delphi/myshare/makefile>make rebuild 
rm *.o hello.out
gcc -o main.o -c main.c
gcc -o func.o -c func.c
gcc -o hello.out main.o func.o
/home/delphi/myshare/makefile>

二、伪目标的使用技巧2
   
绕开.PHONY关键字定位伪目标
    在开始这个技巧之前,首先来看一个原理
   
如果一个规则没有命令或者依赖,并且其目标不是一个存在的文件名,那么在执行此规则时,目标总是会被认为最新的

FORCE:

如上的规则只有一个目标FORCE,没有依赖、没有命令,只要makefile目录下没有文件名为FORCE的文件,那么make FORCE时,命令总是被执行(当然这里的命令为空),有了以上理解,来看下如下的makefile

clean : FORCE
    rm -f *.o hello.out

FORCE:

clean依赖的目标FORCE既没有依赖也没有命令,那么FORCE这个目标总是被认为是最新的,所以每次执行make clean时,rm *.o hello.out 命令总是被执行,不管目录下有没有clean这个文件存在(因为其依赖FORCE总是被认为最新的),

/home/delphi/myshare/makefile>make clean
rm -f *.o hello.out
/home/delphi/myshare/makefile>make clean
rm -f *.o hello.out
/home/delphi/myshare/makefile>

小结:
    - 默认情况下,make认为目标对应着一个文件
    - .PHONY用于声明一个伪目标伪目标不对应实际的文件
    - 伪目标的本质是make中特殊目标.PHONY的依赖
    - 使用伪目标可以模拟"函数调用"

以上内容参考《狄泰软件学院》操作系统篇之 - makefile专题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值