GNU Make 忽略通配符指定的虚假规则?

GNU Make ignoring a phony rule specified by wildcard?

我正在学习一些关于将一些 C 代码编译成特定程序集的课程。我决定应该手动检查生成的程序集,所以我想出了 less something.s 作为 "test" 规则。

作为 Make 的新手,我写了这个 Makefile:

CODES := a

LESS ?= less
CODES_TEST := $(patsubst %,%-test,${CODES})

.PHONY: all test ${CODES_TEST} clean

all: $(patsubst %,%.s,${CODES})

test: all

%-test: %.s
        ${LESS} $^

%.s: %.c
        ${CC} ${CFLAGS} -S -o $@ $^

clean:
        rm -f *.o *.s

我有这个最小的 a.c 文件:

int asdfg(void) { return 54321; }

然后我在 Bash 中输入 make a-test,期待 less 显示 a.s 的内容,却被告知:

make: Nothing to be done for 'a-test'.

无论 a.s 是否存在,我都会得到上述响应,如果我执行 make a.s 或只是 make(隐含地 运行 是第一条规则,它会正常生成, all).

我检查了我的 Makefile,我认为我没有输入错误或其他简单错误。

  1. 以上Makefile我错过了什么?
  2. 当我 运行 make a-test 时如何让 Make 执行 less a.s

a-test 没有什么可做的,因为唯一的规则是隐式模式规则:

%-test: %.s
        ${LESS} $^

并且,根据手册 4.6 Phony Targets

The implicit rule search (see Implicit Rules) is skipped for .PHONY targets.

而且,由于它是 .PHONY,它的不存在确实使它过时了。

为了解决这个问题,同时保留 phoiness,替换:

%-test: %.s
        ${LESS} $^

与:

${CODES_TEST}: %-test: %.s
    ${LESS} $^

那么该规则是静态模式规则,不再是隐式规则。