Makefile: $ (eval $ (call ...)) в рецепте с расширением переменной - PullRequest
0 голосов
/ 23 марта 2020

Я хотел бы понять, как правильно проверить значение вывода оболочки. Это мой кусок кода:

DB := my_database
WORKING_SCHEMA := toto
export WORKING_SCHEMA

check_working_schema = $(shell echo "SELECT EXISTS ( \
                       SELECT 1 FROM pg_catalog.pg_namespace \
                       WHERE nspname = :'sel_schema'\
                       ); " | psql -d $(DB) -q -t -A --variable sel_schema=$$1)

$(info $(check_working_schema))

.PHONY: rule1
rule1 :
ifeq "$(eval $(call check_working_schema, $(WORKING_SCHEMA)))" "t" 
        $(info in true part)
else
        $(info in false par)
endif

Тест не проходит, я не знаю, где ошибка.

Ответы [ 2 ]

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

Спасибо,

после долгих чтений я наконец нашел решение.

Я был сбит с толку, потому что хочу экранировать вторую переменную, переданную psql. Значение $ (DB) одинаково во всем Makefile, но имя схемы может отличаться.

Так вот мое решение:

DB = my_db
# first instanciation of working_schema
WORKING SCHEMA = toto

DB := $(strip $(DB))
WORKING_SCHEMA := $(strip $(WORKING_SCHEMA))

checking_working_schema =$$(shell echo -e "\\\timing of \n\
             SELECT EXISTS ( \
                   SELECT 1 \
                   FROM pg_catalog.pg_namespace \
                   WHERE nspname = :'sel_schema' \
             );" \
             | psql -d $(DB) -q -t -A --variable sel_schema=$1)

$(eval working_schema_exist:=$(call checking_working_schema,$(WORKING_SCHEMA)))

ifeq "$(working_schema_exist)" "t"
  $(info in true part)
else
  $(info in false part)
endif

, затем позже я изменяю значение $ ( WORKING_SCHEMA).

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

Здесь есть несколько заблуждений. Самая важная вещь, которую нужно понять, это то, что когда make оценивает функцию eval, результатом этой оценки является пустая строка. Eval используется для интерпретации синтаксиса make ... он похож на оператор make include, за исключением того, что вместо файла он "включает" строку.

Скажем так:

ifeq "$(eval ...)" "t"

никогда не может работать, потому что первое предложение всегда будет пустой строкой.

Следующее, что нужно понять, это то, что, как указано выше, eval ожидает получить синтаксис make-файла. Но результаты функции call будут выводом оператора psql, который определенно не является синтаксисом make-файла.

Я не уверен, почему вы используете eval здесь. Почему бы просто не использовать:

ifeq "$(call check_working_schema, $(WORKING_SCHEMA))" "t" 

?

Кроме того, ваша функция check_working_schema неверна, поскольку она экранирует аргумент $1; Вы хотите, чтобы этот аргумент был расширен; в этом весь смысл использования call.

и FWIW, я бы также использовал $(strip ...), потому что make чувствителен к пробелам:

check_working_schema = $(strip $(shell echo "SELECT EXISTS ( \
                       SELECT 1 FROM pg_catalog.pg_namespace \
                       WHERE nspname = :'sel_schema'\
                       ); " | psql -d $(DB) -q -t -A --variable sel_schema='$1'))
...