Make не поддерживает нотацию с обратной косой чертой? - PullRequest
1 голос
/ 11 марта 2020

Сценарий

У меня возникли проблемы с попыткой присвоить значения из команды переменной в make-файле. Использование нотации backtick, кажется, работает нормально, но как только я использую более современную нотацию $(pwd), значение переменной ничего не возвращает.

$ cat Makefile
FOO=moo
BAR=$(pwd)
BAZ=`pwd`

all: foo bar baz

foo: 
    @echo foo:$(FOO)';'
bar:
    @echo bar:$(BAR)';'
baz:
    @echo baz:$(BAZ)';'
$ make all
foo:moo;
bar:;
baz:/home/mazunki;

Как видите, FOO и BAZ работают как положено , Но не БАР.

Задача

Давайте теперь посмотрим на мою проблему, добавив еще несколько примеров. Я пропускаю эхо, как вы поняли.

$ cat Makefile
SHELL=/bin/env bash

FOO=dog
BAR=$(pwd)
BAZ=`pwd`
QUZ=`$(FOO)`/cat
ZOT=`\`FOO\``/owl
BIM=`$(BAZ)`/rat
BAM=`\`BAZ\``/pig
BUM=`BUM`/fox

all: foo bar baz quz zot bim bam bum
# targets for all the things

$ make
foo:dog;
bar:;
baz:/home/mazunki;
bash: dog: command not found
quz:/cat;
bash: FOO: command not found
zot:/owl;
bim:pwd/rat;
bash: BAZ: command not found
bam:/pig;
bash: BAZ: command not found
bum:/fox;

У меня действительно были надежды на BIM. Но, к сожалению, он только возвращает команду, которую я хотел выполнить вместо. Я попытался добавить еще один слой $() и / или ``, но вместо этого получился пустой вывод.

Мой желаемый результат - это то, что я получу, запустив echo -n $(pwd)/rat в * 1023. *. Ни один из моих проверенных примеров не позволяет мне сделать это. Я хочу иметь возможность сделать это, так как некоторые команды, которые я использую для своих переменных предисловия, основаны на начальных настройках, например:

# User settings
ROOT=`pwd`
SRCPATH=$(ROOT)/src/
OBJPATH=$(ROOT)/objects/

# Scripting
SRCFILES=`find $(SRCPATH) -name '*.ext' -printf '%p '`
OBJFILES=`find $(SRCPATH) -name '*.ext' -printf '$(OBJPATH)/%p ' | sed 's/^$(SRCPATH)/^$(OBJPATH)//g; s/.ext;/.obj;/g; s/;$//g'`

Это может выглядеть как запутанный сценарий, но я ' Я делаю это по двум основным причинам: я хочу, чтобы он был легко настраиваемым, без необходимости редактирования самих команд, а также потому, что я хочу научиться правильно создавать файлы Makefile.

Ответы [ 3 ]

4 голосов
/ 11 марта 2020

Нет, Makefiles не поддерживают обратные ссылки таким образом. Make-файлы не являются сценариями оболочки и вообще не разделяют синтаксис с bash.

Ваш пример с BAZ только работает, потому что обратные ссылки в итоге копируются буквально в оболочку, поэтому переменная Make BAZ содержит `pwd` (, а не /home/mazunki), и при введении в команду оболочки запускает оболочку echo `pwd`. Ни в коем случае Make никоим образом не интерпретировал обратные сигналы.

Чтобы вызвать команду оболочки из make, вы можете использовать $(shell ...):

var := $(shell pwd)
foo:
        @echo $(var)

Обратите внимание, что команда также является выражением Make, а не командой shell напрямую, поэтому любая $ s, которые вы хотите передать основной оболочке, должны быть экранированы.

1 голос
/ 11 марта 2020

Make не поддерживает backticks. Makefiles не являются сценариями оболочки. Однако make-файлы запускают сценарии оболочки, а сценарии оболочки поддерживают обратные ссылки. Вы написали это:

$ cat Makefile
FOO=moo
BAR=$(pwd)
BAZ=`pwd`

all: foo bar baz

foo: 
        @echo foo:$(FOO)';'
bar:
        @echo bar:$(BAR)';'
baz:
        @echo baz:$(BAZ)';'
$ make all
foo:moo;
bar:;
baz:/home/mazunki;

Присваивание переменных просто создает переменные, содержащие эти буквенные строки, поэтому FOO содержит строку moo, BAR содержит строку $(pwd), а BAZ содержит строка `pwd`.

Make заменяет только те переменные, которые начинаются с $ (возможно, вы уже можете понять, почему ваш make-файл не работает так, как вы хотели). Больше ничего особенного делать не приходится. Поэтому, когда make запускает рецепт для foo, он заменяет переменную make $(FOO) значением moo и запускает команду оболочки echo foo:moo';'. Когда make запускает рецепт для baz, он заменяет $(BAZ) на `pwd` и запускает команду оболочки:

echo baz:`pwd`';'

и shell (не make) расширяет обратные ссылки для вас.

Когда make запускает рецепт для bar, он заменит $(BAR) значением $(pwd), которое является другой переменной make, которая будет расширена, и эта переменная make pwd не задано, поэтому make расширяет это до пустой строки и запускает команду оболочки echo bar:';'.

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

BAR=$$(pwd)

, тогда все будет работать так, как вы ожидаете.

Вы действительно должны прочитать https://www.gnu.org/software/make/manual/html_node/Reference.html и связанные страницы.

0 голосов
/ 11 марта 2020

Расширить ответ { ссылка } на { ссылка }, добавив рабочий пример:

SHELL=/bin/env bash

FOO=$(shell pwd)
BAR=$(FOO)/src
BUZ=ext

all: foo bar baz

foo: 
    @echo foo:$(FOO)';'  # returns /home/mazunki
bar:
    @echo bar:$(BAR)';'  # returns /home/mazunki/src
baz:
    find $(BAR) -name '*.$(BUZ)'  # returns all files /home/mazunki/src/**/*.ext
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...