递归调用中的条件测试

Conditional test in recursive make call

我有以下源代码树:

src
app1
├── Makefile
app2
├── 
app3 
├── Makefile

我想在每个应用程序文件夹中调用 make,为此我有以下代码:

APPS := $(wildcard $(APPS_DIR)/app*)

apps: $(APPS)
$(APPS):
ifneq ("$(wildcard $@/Makefile)","")
    @echo "Building $(patsubst $(APPS_DIR)/%, %, $@)..."
    @$(MAKE) -s -C $@
else
    @echo "No Makefile found for $(patsubst $(APPS_DIR)/%, %, $@)..."
endif
.PHONY: apps $(APPS)

没有条件测试一切正常,我需要避免在应用程序文件夹没有 Makefile 文件的情况下从 make 输出错误。

make[1]: *** No rule to make target 'clean'. Stop. make: *** [Makefile:203: /home/ubuntu/project/apps/app2] Error 2

怎么了?

即使您的问题未标记为 GNU make,您显然使用的是 GNU make 语法,所以我会这样回复。

您不能在 ifneq 等条件语句中使用 $@ 等自动变量,因为条件语句在 读取 makefile 时被解析 但自动变量是直到很久以后才设置,当规则是 运行.

在解析 makefile 时,没有设置像 $@ 这样的变量,因此它们解析为空字符串。

你必须使用 shell 语法来编写条件语句,而不是 make 语法:

$(APPS):
        if [ -n "$(wildcard $@/Makefile)" ]; then \
            echo "Building $(@F)..."; \
            $(MAKE) -s -C $@; \
        else \
            echo "No Makefile found for $(@F)..."; \
        fi

或者,如果您担心没有 POSIX shell 的系统的可移植性,您可以使用 GNU make 的 if 函数:

$(APPS):
        $(if $(wildcard $@/Makefile), \
            echo "Building $(@F)..."; \
            $(MAKE) -s -C $@, \
            echo "No Makefile found for $(@F)...")