Использование условных правил в make-файле - PullRequest
13 голосов
/ 11 января 2012

Я фиксирую намерение Makefile в псевдокоде, затем указываю проблемы, которые у меня есть.Я ищу Makefile, который более удобен для пользователя в тестовой среде.Правильное использование Makefile является одним из следующих:

    make CATEGORY=parser TEST=basic.
    make ALL

Если пользователь дает «ПРОСТО» команды, как указано ниже, он должен напечатать сообщение «КАТЕГОРИЯ определена, ТЕСТ не определен» и наоборот.

    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 не работает.Эхо должно помочь пользователю с правильным использованием.

Ответы [ 2 ]

20 голосов
/ 11 января 2012

Проблема в том, что echo принадлежит оболочке;Make может передать его оболочке в команде, но 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
3 голосов
/ 11 января 2012

Эти строки сомнительны:

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 добавляет в make-файл, язык в make-файле является декларативным, а не процедурным языком.


Другой способ справиться с этим - определить значения по умолчанию для макросов:

CATEGORY = advanced
TEST     = all

Определить значения по умолчанию, которые делают что-то полуразумное; Позвольте пользователю переопределить значение по умолчанию, если они хотят. Вы можете иметь правило, например:

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

Вы можете оставить help в качестве первого правила. У меня есть несколько каталогов, где первое правило:

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

Это эквивалентно тому, что у вас есть (за исключением того, что make не выводит команду перед запуском, поэтому я вижу только сообщение вместо командной строки echo и сообщение; это @ в работе). Этот make-файл также содержит правило all, которое обычно является наиболее разумным первым (по умолчанию) правилом.

...