我用伪代码捕获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
我的问题是:
Makefile中的规则是否可以选择(使用ifdef选择规则和目标)。
回声不起作用。 echo应该帮助用户正确使用。
答案 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 列,否则会导致错误强>。与缩进问题相比,回声是一个小问题。