我有一个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,其将执行clean并all 按此顺序.我没有看到如何正确实现正确的订购.
我所看到的解决方案对我来说是错误的.
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取决于b和c,但是如果b或者c被采取,它不会强制执行a规则.它与排序依赖项无关.
我现在看到的唯一选择是启动一个新的make实例
rebuild : clean
make build
Run Code Online (Sandbox Code Playgroud)
我真的想避免启动一个新的make实例来做那样简单的事情!
我做了一些关于SO的研究.我见过类似的问题,但没有正确答案.对于我的知识,制作目标.PHONY或使用仅限订单依赖性不是解决方案.
首先,在规则中并非如此:
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)