这个怎么样干净?

时间:2016-06-23 21:29:45

标签: makefile

我正在学习更多关于makefile的知识,并且遇到了一个我不太了解的例子。 make clean发生了什么?它强行删除/ obj中的所有目标文件,但之后我就丢失了。我知道它也删除了exe文件,但是如何在代码中翻译?

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

ODIR=obj
LDIR =../lib

LIBS=-lm

_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = hellomake.o hellofunc.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


$(ODIR)/%.o: %.c $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

../hellomake: $(OBJ)
        gcc -o $@ $^ $(CFLAGS) $(LIBS)

.PHONY: clean

clean:
        rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~

1 个答案:

答案 0 :(得分:3)

让我们来看看

rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~

make做的第一件事是扩展$(...)变量,导致:

rm -f obj/*.o *~ core /*~

最后一部分可能是一个错误:INCDIR未定义,因此它扩展为空。你的意思是$(IDIR)吗?

make做的第二件事是通过/bin/sh -c ...运行生成的行。 shell扩展了通配符之类的东西。

我们假设obj中的目标文件是hellomake.ohellofunc.o。然后obj/*.o变为obj/hellofunc.o obj/hellomake.o

*~匹配当前目录中以~结尾的所有文件。你为什么要有这样的文件?因为当您使用emacs编辑文件foo时,默认情况下会保留backup copy under foo~。所以这是为了删除emacs备份文件。

core是您启用core dumps时通常会遇到的,并且您运行的程序崩溃(并且您没有使用systemd)。它可以用来调试崩溃。

最后一个模式看起来与INCDIR中的emacs备份文件匹配,但由于未设置,它会尝试在根目录/中查找备份文件。通常,/中根本没有文件,更不用说emacs备份了。

如果模式不匹配任何文件,则shell的默认行为是保持未展开状态。所以最后一部分(/*~)很可能保持原样。假设您当前目录中没有备份文件,因此*~也是单独的:

rm -f obj/hellofunc.o obj/hellomake.o *~ core /*~

这一行运行rm,传递一个字符串数组作为参数:

{ "rm", "-f", "obj/hellofunc.o", "obj/hellomake.o", "*~", "core", "/*~" }

rm(遵循惯例)扫描其以-开头的字符串的参数,它作为选项处理。在这种情况下,有一个选项ff(“强制”)告诉rm不要询问您没有写入权限的文件;无论如何都要删除它们。它还可以抑制您尝试删除不存在的文件时通常会遇到的错误。 (特别是,你可能没有一个字面上称为*~的文件。)

所以整件事删除

  • obj/
  • 中的目标文件 当前目录中的
  • core
  • 当前目录中的emacs备份文件
  • ema /中的备份文件(可能不存在,如果存在,则可能无权删除)

同时忽略任何错误。