【问题标题】:Makefile default rule patternMakefile 默认规则模式
【发布时间】:2021-04-14 10:53:36
【问题描述】:

只是尝试使用这个骨架编写一个条件 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 变量被禁用。我不知道这样做的正确方法。尝试了一些选项:

选项1,使用骨架示例,始终打印字符串“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.

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

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

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

【问题讨论】:

    标签: makefile default target rules


    【解决方案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

    【讨论】:

    • $(TARGET)% 中删除%。将它放在这里并没有帮助,因为% 必须至少匹配一个字符。它不能匹配任何字符。
    • 感谢您的回答,是的,这解决了我的问题,但是您认为仅使用一条规则就可以解决此问题吗?
    • @MadScientist:是的,我知道,这就是重点,这就是我添加规则的原因。如果我删除了%,我的makefile 将无法工作。
    • 抱歉,我看错了你的答案,我以为第一个是$(TARGET)-%。我的错!
    • @alcastell 您可以改用.DEFAULT 目标;见gnu.org/software/make/manual/html_node/Last-Resort.html
    【解决方案2】:

    正如@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
    

    非常感谢您的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-18
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多