Makefile 默认规则模式

Makefile default rule pattern

只是尝试使用此框架编写条件 Makefile:

TARGET = test

ifeq ($(FOO),y)

$(TARGET):
    @echo This is test
$(TARGET)-a:
    @echo This is test-a
$(TARGET)-b:
    @echo This is test-b

else
$(info FOO is disabled)
endif

当 FOO 条件为真时,基于 TARGET 变量的规则集(由一个 $(TARGET) 和一组 $(TARGET)-substring 组成)按预期工作:

$ make test
This is test

$ make test-a
This is test-a

当 FOO 条件为假时,我想为我所有的目标定义一个默认规则,只是为了在屏幕上报告 FOO 变量被禁用。我不知道这样做的正确方法。尝试了一些选项:

Option1,使用框架示例,总是打印字符串“FOO is disabled”,但会产生错误:

$ make test-a
FOO is disabled
make: *** No rule to make target 'test-a'.  Stop.

$ make test  
FOO is disabled
make: *** No rule to make target 'test'.  Stop.

方案二,如果尝试这样修改false规则:

else
$(TARGET)-%:
    $(info FOO is disabled)
endif

然后所有 $(TARGET)-substring 目标都按预期工作:

$ make test-a
FOO is disabled
make: 'test-a' is up to date.

$ make test-b
FOO is disabled
make: 'test-b' is up to date.

但是当 $(TARGET):

时这条规则失败了
$ make test
make: *** No rule to make target 'test'.  Stop.

选项 3,如果尝试删除选项 2 中定义的错误规则上的连字符:

else
$(TARGET)%:
    $(info FOO is disabled)
endif

然后使 $(TARGET) 执行编译 test.o 目标文件的默认规则:

$ make test
FOO is disabled
cc   test.o   -o test
cc: error: test.o: No such file or directory
cc: fatal error: no input files
compilation terminated.
make: *** [<builtin>: test] Error 1

我变得有点疯狂,试图满足这个默认规则。请提供一些帮助,这将非常有用。谢谢!

有几种方法可以解决这个问题,但最简单的可能就是添加另一条规则:

else

$(TARGET):
    @echo FOO is disabled

$(TARGET)%:
    @echo FOO is disabled

endif

(我把$(info ...改成@echo ...因为后者只有在Make执行规则时才会运行,而前者会运行如果条件定义了那些规则,即使目标是其他东西。)

编辑: 是的,只用一个规则就可以解决这个问题,方法不止一种,但没有完美的方法。

这是一种方法:

TARGET = tes

...

else

$(TARGET)%:
    @echo FOO is disabled

endif

请注意,test 的最后一个字符已被删除。好消息是这条规则将适用于 testtest-atest-b;坏消息是它也适用于 tesw.

正如@MadScientist 所说,.DEFAULT 规则解决了只有一个 Makefile 时的问题。所以这将是最终的 Makefile:

TARGET = test

ifeq ($(FOO),y)

$(TARGET):
    @echo This is test
$(TARGET)-a:
    @echo This is test-a
$(TARGET)-b:
    @echo This is test-b

endif

.DEFAULT:
    @echo This is the default rule

非常感谢您的帮助!