在 makefile 中使用条件规则
我用伪代码捕获 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
我的问题是:
- < p>Makefile 中的规则是否可以选择性(使用 ifdef 选择规则和目标)。
回声不起作用。 echo 应该帮助用户正确使用。
I capture the intent of the Makefile in pseudo code, then indicate the issues I have. I'm looking for a Makefile which is more user friendly in a test environment. The correct usage of the Makefile is one of the below.
make CATEGORY=parser TEST=basic.
make ALL
If a user gives "JUST" the commands as indicated below, it should print a message saying "CATEGORY defined TEST undefined" and vice-versa
make CATEGORY=parser
make TEST=basic
I tried writing the Makefile in following ways, but it errors out:
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
The questions I have are:
Whether the rules in a Makefile can be selective (using ifdef to select the rules and targets).
echo doesn't work. echo should help the user with correct usage.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题是
echo
属于 shell; Make 可以通过命令将其传递给 shell,但 Make 无法执行它。使用info
代替:如果您希望规则是有条件的:
The problem is that
echo
belongs to the shell; Make can pass it to the shell in a command, but Make cannot execute it. Useinfo
instead:If you want the rules to be conditional:
这里最大的问题是所有
ifdef
/ifndef
/ifeq
/... 语句必须位于第 0 列,否则它们将导致错误。与压痕问题相比,回声是一个小问题。The biggest issue here is that all
ifdef
/ifndef
/ifeq
/... statements must be at column 0 or they it will results in an error. The echo is a minor issue compared with the indentation issue.这些行是可疑的:
您需要在
echo
和字符串之间有一个空格,并且字符串需要终止:这些行是可疑的:
当然您需要在第二个字符之前有一个
endif
其他
? (即使它在语法上不是强制性的,我也会推荐它。)此外,
make
仅执行诸如echo
之类的命令,在处理目标(规则)时应该执行 这些命令。它不会在那里执行echo
;它只会反对你不能定义命令而不是目标的操作。尽管 GNU Make 添加到 makefile 中的所有内容,makefile 中的语言都是声明性语言,而不是过程性语言。处理此问题的另一种方法是定义宏的默认值:
定义执行半合理操作的默认值;如果用户愿意,可以让他们覆盖默认值。您可以制定如下规则:
您可以将
help
保留为第一条规则。我有一些目录,其中第一条规则是:这与您所拥有的相同(除了
make
在运行命令之前不会回显命令,因此我只看到消息而不是回显命令行,并且消息;这就是@
的作用)。它来自的 makefile 也有一个规则all
,否则通常是最明智的第一(默认)规则。These lines are dubious:
You need a space between
echo
and the string, and the string needs to be terminated:These lines are dubious:
Surely you need an
endif
before the secondelse
? (Even if it is not syntactically mandatory, I'd recommend it.)Additionally,
make
only executes commands such asecho
is supposed to be when processing a target (rule). It won't executeecho
there; it will simply object that you cannot define commands without them being actions for a target. Despite everything that GNU Make adds to a makefile, the language in a makefile is a declarative language and not a procedural language.Another way of handling this is to define default values for the macros:
Define default values that do something semi-reasonable; let the user override the default if they want to. You can have a rule such as:
You can leave
help
as the first rule. I have some directories where the first rule is:This is equivalent to what you have (except that
make
does not echo the command before running it, so I only see the message instead of the echo command line and the message; that's the@
at work). The makefile this comes from also has a ruleall
which is otherwise usually the most sensible first (default) rule.