在 makefile 中使用条件规则

发布于 2024-12-25 22:19:15 字数 1040 浏览 0 评论 0原文

我用伪代码捕获 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. < p>Makefile 中的规则是否可以选择性(使用 ifdef 选择规则和目标)。

  2. 回声不起作用。 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:

  1. Whether the rules in a Makefile can be selective (using ifdef to select the rules and targets).

  2. echo doesn't work. echo should help the user with correct usage.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

葬花如无物 2025-01-01 22:19:15

问题是 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

The problem is that echo belongs to the shell; Make can pass it to the shell in a command, but Make cannot execute it. Use info instead:

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

If you want the rules to be conditional:

ifdef CATEGORY
ifdef TEST
$(CATEGORY):
    whatever
else
$(info TEST not defined)
else
$(info CATEGORY not defined)
endif
清风夜微凉 2025-01-01 22:19:15

这里最大的问题是所有 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.

陈年往事 2025-01-01 22:19:15

这些行是可疑的:

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 其他? (即使它在语法上不是强制性的,我也会推荐它。)

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 在运行命令之前不会回显命令,因此我只看到消息而不是回显命令行,并且消息;这就是 @ 的作用)。它来自的 makefile 也有一个规则 all,否则通常是最明智的第一(默认)规则。

These lines are dubious:

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

You need a space between echo and the string, and the string needs to be terminated:

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

These lines are dubious:

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

Surely you need an endif before the second else? (Even if it is not syntactically mandatory, I'd recommend it.)

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

Additionally, make only executes commands such as echo is supposed to be when processing a target (rule). It won't execute echo 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:

CATEGORY = advanced
TEST     = all

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:

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

You can leave help as the first rule. I have some directories where the first rule is:

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

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 rule all which is otherwise usually the most sensible first (default) rule.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文