2017-01-21 2 views
0

С помощью этого Makefile я не уверен, почему я получил недостающую ошибку разделителя.Отсутствует отдельная ошибка из make-файла

define foo 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 

$(call foo,hello) 

$(info $(a)) 
$(info $(b)) 

all: ; 

Если я однако заменяет первое Eval с этим,

$(eval a := $(1)) \ 

то ошибка уходит. eval не раскрывается ни к чему, и он доволен только одной оценкой внутри define. Но я не уверен, почему он жалуется в этом случае, и почему задняя косая черта решает его.

ответ

1
define foo 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 

bar:=$(call foo,hello) 

$(info $(a)) 
$(info $(b)) 
$(info bar=[$(bar)]) 

all: ; 

Запуск этой Makefile выходы:

$ make -f Makefile.sample 
hello 
hello 
bar=[ 
] 
make: 'all' is up to date. 

Так $ функция (Foo) выводит символ новой строки. Он должен либо выводить ничего, либо значение должно быть записано в переменной или в ловушке с $ (eval) или $ (strip).

$(eval a := $(1)) \ не приводит к появлению новой строки из $ (foo), поэтому она устраняет проблему.

Альтернативы добавления обратной косой черты в ваших $ (Foo) являются:

# 1:

define fooBody 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 
foo = $(strip $(call fooBody,$1,$2)) 

# 2

define fooBody 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 
foo = $(eval $(call fooBody,$1,$2)) 

# 3

$(strip $(call foo,hello)) 

# 4

$(eval $(call foo,hello)) 

# 5

.:=$(call foo,hello) 

Мой личный выбор # 1.

+0

Вам не нужно полосу или Eval, если вы назначаете результаты в переменной; это нормально для переменной, содержащей символ новой строки (действительно, 'fooBody' уже делает ...) – MadScientist

+0

strip и eval для случаев, когда результат вызова функции не присваивается переменной. –

+0

О, я понимаю, что вы имеете в виду, это заменяет foo не вызовом foo. Гектометр Лично мне это не нравится: это сбивает с толку. Я понимаю, что это позволяет вам просто использовать 'foo'. Лично я не поклонник всей идиомы добавления eval в такие переменные; обычным способом было бы просто назначить задания в 'foo' и eval результаты вызова. Но, возможно, в реальных make-файлах это имеет больше смысла. – MadScientist

1

Результаты РАСШИРЕНИЯ call в одной новой строки (потому что, как вы говорите, как eval «s развернуть в пустую строку. Когда сделайте пытается разобрать, что она не понимает его и выдает эту ошибку.

Важно, чтобы make нарушил вход в логические строки до, он пытается запустить расширение. Поэтому после завершения расширения make ожидает увидеть одну строку вывода и не понимает новые строки существующих в этой единственной строке.

Возможно, это можно было бы обработать лучше, если бы вы захотели подать ошибку при https://savannah.gnu.org/bugs/?func=additem&group=make

ETA На самом деле я проверил и это уже зафиксировано в GNU сделать 4.2:

$ make-4.1 
Makefile:5: *** missing separator. Stop. 

$ make-4.2 
make: *** No targets. Stop. 
Смежные вопросы