Makefile $(command) не работает, а `command` работает

Дело в том, что когда я писал Makefile для своего проекта, когда мне нужно было определить имя текущей ветки, в правиле make я сделал это:

check_branch:
    if [ "$(git rev-parse --abbrev-ref HEAD)" == "master" ]; then \
    echo "In master"
    else \
    echo "Not in master"; \
    fi

Когда я вызвал make check_branch, "$(git rev-parse --abbrev-ref HEAD)" не сработал, он вернул "" пустую строку. Но вместо этого, когда я изменил $() на ` `, все заработало отлично.

check_branch:
    if [ "`git rev-parse --abbrev-ref HEAD`" == "master" ]; then \
    echo "In master"
    else \
    echo "Not in master"; \
    fi

Почему $() не работает, а `` работает? Только для команды "git".

Обратите внимание, что в моем Makefile я обычно использовал $() во многих правилах.

Спасибо :)


person phnah    schedule 31.03.2013    source источник
comment
См.: Эскейпирование в Makefile. Проблема в том, что $ (знак доллара) является особенным для make. Если вы используете двойной доллар, это должно сработать.   -  person artless noise    schedule 31.03.2013
comment
Вы также должны позаботиться о том, чтобы убедиться, что вы находитесь в каталоге в иерархии git.   -  person artless noise    schedule 31.03.2013
comment
@artlessnoise: ты прав, большое спасибо. :)   -  person phnah    schedule 31.03.2013


Ответы (2)


Внутри рецептов вы должны избегать знаков доллара, чтобы интерпретировать их оболочкой. В противном случае Make воспринимает $(git ...) как встроенную команду или переменную и пытается ее вычислить (разумеется, безуспешно).

check_branch:
    if [ "$$(git rev-parse --abbrev-ref HEAD)" == "master" ]; then \
    ...
person Eldar Abusalimov    schedule 31.03.2013

В строках оболочки вы пишете команды оболочки, как в сценарии оболочки. Вот почему работает вторая операция.

Если вы хотите, чтобы Make оценивал команду git вне оболочки, вы можете включить операцию в функцию оболочки, например:

$(shell git rev-parse --abbrev-ref HEAD)

И вам должно быть хорошо идти, хотя я часто реализую такие вещи, как:

branch := $(shell git rev-parse --abbrev-ref HEAD)
target:dep
     mkdir -p build/$(branch)

Или что-то вдоль этих линий.

person tychoish    schedule 31.03.2013