Como imprimir uma variável no makefile

Na minha makefile, tenho uma variável 'NDK_PROJECT_ path', a minha pergunta é: como posso imprimi-la quando se compila?

li O Make file echo a mostrar o texto "$PATH " e tentei:

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

ambos me dão

"build-local.mk:102: *** missing separator.  Stop."
Alguém sabe porque não está a funcionar comigo?

Author: Community, 2013-05-09

14 answers

Você pode imprimir as variáveis à medida que o makefile é lido (assumindo que o GNU make como marcou esta questão apropriadamente) usando este método (com uma variável chamada "var"):

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

Pode adicionar esta construção a qualquer receita para ver o que o make irá passar para a linha de comandos:

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

Agora, o que acontece aqui é que faz armazenar toda a receita ({[[2]}) como uma única variável recursivamente expandida. Quando o make decide executar a receita (por exemplo, quando o diz para compilar all), expande a variável, e então passa cada linha resultante separadamente para a shell.

Então, em detalhes dolorosos:
  • Expande $(info $$var is [${var}])echo Hello world
  • para fazer isto primeiro expande $(info $$var is [${var}])
    • $$ torna-se literal $
    • ${var} torna-se :-) (diz)
    • o efeito secundário é que $var is [:-)] aparece no standard out
    • a expansão do $(info...) embora esteja vazia
  • a marca é deixada com echo Hello world
    • fazer impressões digitais echo Hello world em stdout primeiro para lhe dizer o que vai pedir à shell para fazer
  • as impressões da concha Hello world na stdout.
 158
Author: bobbogo, 2018-06-20 18:35:57
De um "Mr. Make post" https://www.cmcrossroads.com/article/printing-value-makefile-variable

Adicione a seguinte regra ao seu Makefile:

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

Então, se quiser descobrir o valor de uma variável makefile, basta:

make print-VARIABLE

E voltará:

VARIABLE = the_value_of_the_variable
 107
Author: Anthony Earl Wong, 2014-09-12 22:46:16

Como 'bobbogo' na resposta acima apontada e de acordo com o Manual GNU Make , você pode usar info / aviso / erro para mostrar texto.

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

Para imprimir variáveis,

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

Quando usar o 'erro', a execução do make irá parar depois de mostrar o texto de erro

 100
Author: tsenapathy, 2018-09-12 10:16:57

Se você simplesmente quer alguma saída, você quer usar $(info) por si só. Você pode fazer isso em qualquer lugar em um Makefile, e ele vai mostrar quando essa linha é avaliada:

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

Irá produzir VAR="<value of VAR>" sempre que criar processos nessa linha. Este comportamento é muito dependente da posição, então você deve se certificar de que a expansão $(info) acontece depois de tudo o que poderia modificar $(VAR) já aconteceu!

Uma opção mais genérica é criar uma regra especial para imprimir o valor de uma variável. De um modo geral, as regras são executadas depois de as variáveis serem atribuídas, de modo que isto irá mostrar-lhe o valor que está realmente a ser usado. (Embora seja possível para uma regra mudar uma variável .) Uma boa formatação ajudará a esclarecer o que uma variável é definida, e a função $(flavor) irá dizer-lhe que tipo de variável é algo. Portanto, nesta regra:

print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
  • $* expande-se para o caule que o % o padrão corresponde à regra.
  • $($*) expande - se para o valor da variável cujo nome é dado por $*.
  • as [ e ] delimitam claramente a expansão variável. Também pode utilizar " e " ou similar.
  • $(flavor $*) diz-te que tipo de variável é. Nota: $(flavor) toma uma variável nome , e não a sua expansão. Por isso, se disser make print-LDFLAGS, terá $(flavor LDFLAGS), que é o que tu queres.
  • $(info text) fornece a saída. O Make imprime text na sua stdout como um efeito secundário da expansão. O a expansão de $(info) embora esteja vazia. Você pode pensar nisso como @echo, mas o importante é que não usa a concha., não precisas de te preocupar com as regras da shell.
  • @true existe apenas para fornecer um comando para a regra. Sem isso, O make {[39] } também produzirá print-blah is up to date. Acho que deixa mais claro que é suposto não haver op.

Executando, você tem

$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]
 38
Author: Jim Nasby, 2017-11-01 15:24:28

Todas as versões de make requerem que as linhas de comandos sejam indentadas com uma página (Não espaço) como o primeiro carácter da linha. Se nos mostrasse toda a regra em vez de apenas as duas linhas em questão, poderíamos dar uma resposta mais clara, mas deveria ser algo como:

myTarget: myDependencies
        @echo hi

Onde o primeiro carácter da segunda linha deve ser TAB.

 6
Author: MadScientist, 2013-05-09 23:35:43

@echo $(NDK_ PROJECT_ Path) é a boa maneira de o fazer. Acho que o erro não vem daí. Geralmente, este erro aparece quando você digitou mal a intendação : acho que você tem espaços onde você deve ter uma aba.

 5
Author: , 2013-05-09 17:45:31

Executar make -n; mostra-lhe o valor da variável..

Makefile...
all:
        @echo $(NDK_PROJECT_PATH)

Comando:

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

Resultado:

echo /opt/ndk/project
 5
Author: ivandcl, 2014-08-12 23:32:19

Este makefile irá gerar a mensagem de erro do' separador em falta':

all
    @echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)

done:
        @echo "All done"

Há uma guia antes da @echo "All done" (Embora a regra e a acção sejam em grande parte supérfluas), mas não antes da @echo PATH=$(PATH).

O problema é que a linha que começa all deve ter um ponto : ou um igual = para indicar que é uma linha de alvo ou uma linha de macro, e não tem nenhum, por isso o separador está em falta.

A acção que ecoa o valor de uma variável deve ser associado a um alvo, possivelmente um alvo falso ou falso. E aquela linha de alvo deve ter dois pontos. Se você adicionar um : Depois de all no exemplo makefile e substituir os espaços iniciais na próxima linha por uma aba, Ele irá funcionar de forma sÃ.

Você provavelmente tem um problema análogo perto da linha 102 no makefile original. Se você mostrou 5 linhas não-em branco, Não-comentários antes das operações echo que estão falhando, provavelmente seria possível terminar o diagnóstico. No entanto, uma vez que a a pergunta foi feita em maio de 2013, é improvável que o broken makefile ainda esteja disponível agora (agosto de 2014), pelo que esta resposta não pode ser validada formalmente. Ele só pode ser usado para ilustrar uma maneira plausível em que o problema ocorreu.

 3
Author: Jonathan Leffler, 2014-08-12 23:28:59
O problema é que o echo só funciona sob um bloco de execução. ou seja, qualquer coisa depois de "xx:"

Então qualquer coisa acima do primeiro bloco de execução é apenas inicialização para que nenhum comando de execução possa ser usado.

Então crie um bloco de execução.
 2
Author: Andy, 2015-12-04 17:56:56

Para imprimir o valor de uma variável pode usar:

rule:
<tab>@echo $(VAR_NAME)

Quando a regra correr, a variável será impressa.

 1
Author: Samuel, 2014-12-31 00:33:14

Isto pode ser feito de uma forma genérica e pode ser muito útil ao depurar um makefile complexo. Seguindo a mesma técnica descrita em outra resposta , pode inserir o seguinte em qualquer makefile:

# 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

Então você pode apenas fazer "make print" para despejar o valor de qualquer variável:

$ make print CXXFLAGS
CXXFLAGS = -g -Wall
 1
Author: Idelic, 2017-05-23 12:10:46

Não é necessário modificar o Makefile.

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

$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE
 1
Author: Talespin_Kit, 2018-02-14 07:49:28

Se não quiser modificar o Makefile em si, pode usar --eval para adicionar um novo alvo, e depois executar o novo alvo, por exemplo

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

Pode inserir o carácter de página necessário na linha de comandos, usando CTRL-V, TAB

Exemplo Makefile de cima:

all: do-something

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

do-something:
        @echo "doing something"
        @echo "running tests $(TESTS)"
        @exit 1
 0
Author: Wade, 2017-03-06 23:00:12

Se usar o android make (mka) @echo $(NDK_PROJECT_PATH) não vai funcionar e dá-lhe um erro *** missing separator. Stop." use esta resposta se está a tentar imprimir variáveis no Android make

NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))
Isso funcionou comigo.
 0
Author: mjalil, 2017-05-23 12:34:51