如何在Makefile中使用'build'和'clean'制作'rebuild'规则?

Cyg*_*sX1 5 makefile

我有一个Makefile,其中包含用于构建小项目和清理它的规则.例如:

CC:=gcc
LD:=gcc
SOURCES:=$(wildcard src/*.c)
OBJS:=$(SOURCES:src/%.c=build/%.o)
TARGET:=bin/program

all: $(TARGET)

$(TARGET): $(OBJS)
    @mkdir -p bin
    $(LD) $+ -o $@

build/%.o: src/%.c
    @mkdir -p build
    $(CC) $+ -c -o $@

clean:
    rm -rf $(OBJS)
    rm -rf $(TARGET)
    rmdir bin
    rmdir build

.PHONY: clean all
Run Code Online (Sandbox Code Playgroud)

我现在在创建规则兴趣rebuild,其将执行cleanall 按此顺序.我没有看到如何正确实现正确的订购.


我所看到的解决方案对我来说是错误的.

rebuild: clean all
.PHONY: rebuild
Run Code Online (Sandbox Code Playgroud)

自然是错误的,因为无法保证依赖关系实际按其外观顺序执行.all可能之前执行clean.

我已经看到了建议仅限订单依赖的答案,例如

rebuild: | clean all
.PHONY: rebuild
Run Code Online (Sandbox Code Playgroud)

据我所知,这并没有解决问题.如果你说它a: | b c意味着a取决于bc,但是如果b或者c被采取,它不会强制执行a规则.它与排序依赖项无关.

我现在看到的唯一选择是启动一个新的make实例

rebuild : clean
    make build
Run Code Online (Sandbox Code Playgroud)

我真的想避免启动一个新的make实例来做那样简单的事情!


我做了一些关于SO的研究.我见过类似的问题,但没有正确答案.对于我的知识,制作目标.PHONY或使用仅限订单依赖性不是解决方案.

Mad*_*ist 6

首先,在规则中并非如此:

rebuild: clean all
Run Code Online (Sandbox Code Playgroud)

all可以在clean 串行运行之前构建(也就是说,没有-j启用并行性).Make总是按照它们在makefile中列出的顺序构建先决条件(包含配方的规则有一个特例,但这里不相关).当使用并行构建时,make仍以相同的顺序遍历依赖树,但由于规则是并行构建的,因此它们可能无法以相同的顺序启动.

但是,你是对的,因为其他原因(目录缓存等),这个规则不是一个好主意.

我建议您使用递归make调用来执行此操作:

.PHONY: rebuild
rebuild:
        $(MAKE) clean
        $(MAKE) all
Run Code Online (Sandbox Code Playgroud)