这是MadScientist 答案的另一种方法。.PHONY
是 GNU 特定的功能,可用于强制make
递归到每个子目录。但是,一些非 GNU 版本make
不支持.PHONY
,因此替代方案是force target。
4.7 没有配方或先决条件的规则
如果一个规则没有先决条件或配方,并且该规则的目标是一个不存在的文件,那么 make 会认为该目标在其规则运行时已被更新。这意味着所有依赖于此目标的目标都将始终运行其配方。
一个例子将说明这一点:
clean: FORCE
rm $(objects)
FORCE:
这里目标“FORCE”满足特殊条件,因此依赖于它的目标清理被迫运行其配方。“FORCE”这个名字没有什么特别之处,但这是一个常用的名字。
如您所见,以这种方式使用 'FORCE' 与使用 '.PHONY: clean' 的结果相同。
使用“.PHONY”更明确、更有效。但是,其他版本的 make 不支持 '.PHONY';因此'FORCE' 出现在许多makefile 中。请参阅虚假目标。
以下是递归make
到每个子目录的最小示例,每个子目录可能包含一个Makefile
. 如果您只是简单地运行make
,则仅处理第一个不确定的子目录。您也可以运行make subdir1 subdir2 ...
.
# Register all subdirectories in the project's root directory.
SUBDIRS := $(wildcard */.)
# Recurse `make` into each subdirectory.
$(SUBDIRS): FORCE
$(MAKE) -C $@
# A target without prerequisites and a recipe, and there is no file named `FORCE`.
# `make` will always run this and any other target that depends on it.
FORCE:
这是另一个顶级虚假目标的示例:all
和clean
. 请注意,从命令行 via 传递的all
和目标分别由每个子目录的和目标处理。clean
$(MAKECMDGOALS)
all
clean
# Register all subdirectories in the project's root directory.
SUBDIRS := $(wildcard */.)
# Top-level phony targets.
all clean: $(SUBDIRS) FORCE
# Similar to:
# .PHONY: all clean
# all clean: $(SUBDIRS)
# GNU's .PHONY target is more efficient in that it explicitly declares non-files.
# Recurse `make` into each subdirectory
# Pass along targets specified at command-line (if any).
$(SUBDIRS): FORCE
$(MAKE) -C $@ $(MAKECMDGOALS)
# Force targets.
FORCE: