Как распечатать переменную в make файле

В моем make файле у меня есть переменная 'NDK_PROJECT_PATH', мой вопрос в том, как я могу ее распечатать при компиляции?

Я читаю Сделать отображение эха в файле "$PATH" string, и я попробовал:

@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)

Оба дают мне

"build-local.mk:102: *** missing separator.  Stop."

Кто-нибудь знает, почему он не работает для меня?

Ответ 1

Вы можете распечатать переменные при чтении make файла (при условии, что GNU make, поскольку вы правильно пометили этот вопрос), используя этот метод (с переменной с именем "var"):

$(info $$var is [${var}])

Вы можете добавить эту конструкцию в любой рецепт, чтобы увидеть, что make перейдет в оболочку:

.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world

Теперь происходит то, что make хранит весь рецепт ($(info $$var is [${var}])echo Hello world) в виде одной рекурсивно раскрытой переменной. Когда make решает запустить рецепт (например, когда вы говорите ему построить all), он расширяет переменную и затем передает каждую результирующую строку отдельно в оболочку.

Итак, в болезненных деталях:

  • Он расширяет $(info $$var is [${var}])echo Hello world
  • Для этого он сначала расширяет $(info $$var is [${var}])
    • $$ становится буквальным $
    • ${var} становится :-) (скажем)
    • Побочным эффектом является то, что $var is [:-)] появляется на стандартном
    • Расширение $(info...) хотя и пустое
  • Сделать осталось с echo Hello world
    • Сделайте отпечатки echo Hello world на stdout, чтобы вы знали, что именно попросит оболочка
  • Оболочка печатает Hello world на стандартный вывод.

Ответ 2

из "Mr. Make post" https://www.cmcrossroads.com/article/printing-value-makefile-variable

Добавьте в свой файл Makefile следующее правило:

print-%  : ; @echo $* = $($*)

Затем, если вы хотите узнать значение переменной makefile, просто:

make print-VARIABLE

и он вернется:

VARIABLE = the_value_of_the_variable

Ответ 3

Как указано в приведенном выше ответе "bobbogo" и согласно руководству GNU Make, вы можете использовать info/warning/error для отображения текста.

$(error   text…)
$(warning text…)
$(info    text…)

Чтобы напечатать переменные,

$(error   VAR is $(VAR))
$(warning VAR is $(VAR))
$(info    VAR is $(VAR))

когда вы используете 'error', выполнение make останавливается после отображения строки ошибки

Ответ 4

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

$(info VAR="$(VAR)")

Будет выводить VAR="<value of VAR>" всякий раз, когда обрабатывает эту строку. Это поведение очень зависит от положения, поэтому вы должны убедиться, что расширение $(info) происходит ПОСЛЕ того, что все, что может изменить $(VAR), уже произошло!

Более общий вариант заключается в создании специального правила для печати значения переменной. Вообще говоря, правила выполняются после назначения переменных, поэтому это покажет вам значение, которое фактически используется. (Хотя для правила можно изменить ). Хорошее форматирование поможет уточнить, к какой переменной задано, и функция $(flavor) сообщит вам какая переменная что-то есть. Итак, в этом правиле:

print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
  • $* расширяется до того, что шаблон % соответствует правилу.
  • $($*) расширяется до значения переменной, имя которой задается $*.
  • [ и ] четко обозначают расширение переменной. Вы также можете использовать " и " или аналогичные.
  • $(flavor $*) сообщает вам, какая именно переменная. ПРИМЕЧАНИЕ: $(flavor) принимает имя переменной, а не ее расширение. Итак, если вы скажете make print-LDFLAGS, вы получите $(flavor LDFLAGS), это то, что вы хотите.
  • $(info text) обеспечивает вывод. Произведите отпечатки text на его stdout как побочный эффект расширения. Расширение $(info) хотя и пусто. Вы можете думать об этом как @echo, но важно, чтобы он не использовал оболочку, поэтому вам не нужно беспокоиться о правилах цитирования оболочки.
  • @true существует только для того, чтобы предоставить команду для правила. Без этого, make также выводит print-blah is up to date. Я чувствую, что @true делает более понятным, что это означает, что это не-op.

Запустив его, вы получите

$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]

Ответ 5

@echo $(NDK_PROJECT_PATH) - хороший способ сделать это. Я не думаю, что ошибка исходит оттуда. Как правило, эта ошибка появляется, когда вы опечатываете намерение: я думаю, у вас есть места, где у вас должна быть вкладка.

Ответ 6

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

myTarget: myDependencies
        @echo hi

где первый символ во второй строке должен быть TAB.

Ответ 7

Запустить make -n; он показывает вам значение переменной..

Makefile...

all:
        @echo $(NDK_PROJECT_PATH)

Команда:

export NDK_PROJECT_PATH=/opt/ndk/project
make -n 

Вывод:

echo /opt/ndk/project

Ответ 8

Этот makefile будет генерировать сообщение об ошибке "missing separator":

all
    @echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)

done:
        @echo "All done"

Там есть вкладка перед @echo "All done" (хотя правило done: и действие в значительной степени избыточные), но не до @echo PATH=$(PATH).

Проблема заключается в том, что строка, начинающаяся с all, должна иметь двоеточие : или равно =, чтобы указать, что это целевая строка или макрокоманда, и она не имеет ни одного, поэтому разделитель отсутствует.

Действие, которое перекликается с значением переменной, должно быть связано с целевой, возможно, фиктивной или целевой PHONEY. И эта целевая линия должна содержать двоеточие. Если вы добавите : после all в примере makefile и замените ведущие пробелы в следующей строке вкладкой, это будет работать нормально.

У вас, вероятно, есть аналогичная проблема вблизи строки 102 в оригинале makefile. Если вы показали 5 непустых строк без комментариев, прежде чем выполняемые эхо-операции не удастся, возможно, будет возможно завершить диагностику. Однако, поскольку вопрос был задан в мае 2013 года, маловероятно, что сломанный makefile все еще доступен (август 2014 года), поэтому этот ответ не может быть официально подтвержден. Его можно использовать только для иллюстрации правдоподобного способа возникновения проблемы.

Ответ 9

Проблема заключается в том, что эхо работает только под исполнительным блоком. то есть после "xx:"

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

Итак, создайте выполнение blocl

Ответ 10

Чтобы напечатать значение переменной, которую вы можете использовать:

rule:
<tab>@echo $(VAR_NAME)

При запуске правила переменная будет напечатана.

Ответ 11

Это можно сделать общим способом и может быть очень полезно при отладке сложного make файла. Следуя той же методике, что описана в другом ответе, вы можете вставить следующее в любой make файл:

# if the first command line argument is "print"
ifeq ($(firstword $(MAKECMDGOALS)),print)

  # take the rest of the arguments as variable names
  VAR_NAMES := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

  # turn them into do-nothing targets
  $(eval $(VAR_NAMES):;@:))

  # then print them
  .PHONY: print
  print:
          @$(foreach var,$(VAR_NAMES),\
            echo '$(var) = $($(var))';)
endif

Затем вы можете просто сделать "сделать печать", чтобы сбросить значение любой переменной:

$ make print CXXFLAGS
CXXFLAGS = -g -Wall

Ответ 12

Нет необходимости изменять Makefile.

$ cat printvars.mak
print-%:
        @echo '$*=$($*)'

$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE

Ответ 13

Если вы не хотите изменять сам Makefile, вы можете использовать --eval для добавления новой цели, а затем выполнить новую цель, например.

make --eval='print-tests: @echo TESTS $(TESTS) ' print-tests

Вы можете вставить требуемый символ TAB в командной строке, используя CTRL-V, TAB

Пример Makefile сверху:

all: do-something

TESTS=
TESTS+='a'
TESTS+='b'
TESTS+='c'

do-something:
        @echo "doing something"
        @echo "running tests $(TESTS)"
        @exit 1

Ответ 14

если вы используете команду android make (mka) @echo $(NDK_PROJECT_PATH), не будет работать и вы получите сообщение об ошибке *** missing separator. Stop." используйте этот ответ, если вы пытаетесь распечатать переменные в android make

NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))

который работал у меня

Ответ 15

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

@echo $ (ошибка NDK_PROJECT_PATH = $ (NDK_PROJECT_PATH))