在makefile中使用条件规则

时间:2012-01-10 22:33:24

标签: makefile conditional-compilation

我用伪代码捕获Makefile的意图,然后指出我遇到的问题。我正在寻找一个在测试环境中更加用户友好的Makefile。 Makefile的正确用法是以下之一。

    make CATEGORY=parser TEST=basic.
    make ALL

如果用户给出“JUST”命令,如下所示,它应该打印一条消息“CATEGORY defined TEST undefined”,反之亦然

    make CATEGORY=parser
    make TEST=basic

我尝试用以下方式编写Makefile,但它出错了:

    help:
        echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case>
        echo"       make ALL

    ifdef CATEGORY
        ifdef TEST
            CATEGORY_TEST_DEFINED = 1
        else
             echo "TEST not defined"
    else
        echo "CATEGORY not defined"
    endif



    ifeq ($(CATEGORY_TEST_DEFINED), 1)
    $(CATEGORY):
        cd $(PROJ)/$(CATEGORY)
        make -f test.mk $(TEST)
    endif

    ifdef ALL
    $(ALL):
         for i in `ls`
         cd $$(i)
         make all
    endif

我的问题是:

  1. Makefile中的规则是否可以选择(使用ifdef选择规则和目标)。

  2. 回声不起作用。 echo应该帮助用户正确使用。

3 个答案:

答案 0 :(得分:20)

问题是echo属于shell; Make可以在命令中将它传递给shell,但Make不能执行它。请改用info

ifdef CATEGORY
$(info CATEGORY defined)
else
$(info CATEGORY undefined)
endif

如果您希望规则是有条件的:

ifdef CATEGORY
ifdef TEST
$(CATEGORY):
    whatever
else
$(info TEST not defined)
else
$(info CATEGORY not defined)
endif

答案 1 :(得分:3)

这些界限可疑:

help:
    echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case>
    echo"       make ALL

您需要echo和字符串之间的空格,并且字符串需要终止:

help:
    echo "Usage: make CATEGORY=<advanced|basic> TEST=<test-case>"
    echo "       make ALL"

这些界限可疑:

ifdef CATEGORY
    ifdef TEST
        CATEGORY_TEST_DEFINED = 1
    else
         echo "TEST not defined"
else
    echo "CATEGORY not defined"
endif

在第二个endif之前你肯定需要else吗? (即使它在语法上不是强制性的,我也会推荐它。)

ifdef CATEGORY
    ifdef TEST
        CATEGORY_TEST_DEFINED = 1
    else
         echo "TEST not defined"
    endif
else
    echo "CATEGORY not defined"
endif

此外,make仅在处理目标(规则)时执行echo之类的命令。它不会在那里执行echo;它只是反对你不能定义命令而不是它们是目标的动作。尽管GNU Make为makefile添加了所​​有内容,但makefile中的语言是一种声明性语言,而不是一种过程语言。


另一种处理方法是定义宏的默认值:

CATEGORY = advanced
TEST     = all

定义做一些半合理的默认值;让用户根据需要覆盖默认值。您可以使用以下规则:

${CATEGORY}/${TEST}: ...dependencies...
    ...actions...

您可以将help作为第一条规则。我有一些目录,第一条规则是:

null:
    @echo "You must specify a target with this makefile!"

这相当于你所拥有的(除了make在运行之前没有回显命令,所以我只看到消息而不是echo命令行和消息;那是@工作中)。来自的makefile也有一个规则all,否则通常是最明智的第一个(默认)规则。

答案 2 :(得分:0)

这里最大的问题是所有 ifdef/ifndef/ifeq/... 语句都必须在第 0 列,否则会导致错误。与缩进问题相比,回声是一个小问题。