伪目标
在我上几篇博客中,我的文件夹下一直是这几个文件:
animal.c human.c Makefile my.h robot.c world.c
我现在在这个文件夹下新建一个文件 clean.c,内容如下:
#include <stdio.h>
int main(int argc, const char *argv[])
{
printf("cleanworld!\n");
return0;
}
并使用gcc clean.c -o clean生成可执行文件 clean, 执行可执行文件 ./clean
打印:clean world! 一切正常。
使用make命令生成 world可执行文件以及中间过程的过渡文件,现在这个文件夹下文件如下:
animal.c clean human.c Makefile my.h robot.o world.c
animal.o clean.c human.o Makefile1 robot.c world world.o
我现在想使用make clean 清除world可执行文件以及中间过程的过渡文件,执行结果如下:
make: `clean' is up to date.
发现Makefile中的clean命令执行不了了。
原因:
多次执行make,你会看到如下结果。
make: `world' is up to date.
因为在Linux中所有的文件都有时间戳属性,编译器会根据时间戳判断当前依赖是否改动,如果依赖文件没有改动,那么执行生成目标的过程只需一次就行了。再次执行make的时候,编译器会告诉你,当前可执行文件都是最新的。我不需要再把生成过程执行一遍了。
我们看一下Makefile中的clean,
clean:
rm$(OBJ) $(OBJS)
make clean去执行Makefile中的命令时,编译器会把clean当作一个目标,这个目标连依赖文件都没有,只要当前文件夹中有clean这个文件时,编译器就会认为这个clean文件我已经生成了,而且是最新的,我不用再往下执行了。
解决这个矛盾就是利用关键字 .PHONY将clean声明为一个伪目标,意思就是clean不是一个目标,但是它又具有目标文件的功能,无论当前文件夹下是否有clean这个文件,都要将clean这个整体执行完。
.PHONY:clean
OBJ =world
OBJS = world.o robot.o human.o animal.o
CC = gcc
CFLAGS = -c -o
$(OBJ): $(OBJS)
$(CC)$(OBJS) -o $(OBJ)
%.o: %.c
$(CC)$^ $(CFLAGS) $@
clean:
rm-f $(OBJ) $(OBJS)