Como posso interromper uma execução de make / makefile com base na variável de makefile que não está sendo definida / avaliada?
Eu vim com isso, mas funciona apenas se o chamador não executar explicitamente um destino (ou seja, executar make
apenas).
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
Acho que algo assim seria uma boa ideia, mas não encontrei nada no manual do make:
ifndef MY_FLAG
.ABORT
endif
Respostas:
TL; DR : use a
error
função :Observe que as linhas não devem ser recuadas. Mais precisamente, nenhuma guia deve preceder essas linhas.
Solução genérica
Caso você teste várias variáveis, vale a pena definir uma função auxiliar para isso:
E aqui está como usá-lo:
Isso geraria um erro como este:
Notas:
A verificação real é feita aqui:
Isso reflete o comportamento da
ifndef
condicional, de modo que uma variável definida com um valor vazio também é considerada "indefinida". Mas isso só é verdade para variáveis simples e variáveis recursivas explicitamente vazias:Conforme sugerido por @VictorSergienko nos comentários, um comportamento ligeiramente diferente pode ser desejado:
E:
Verificação específica do alvo
Também é possível estender a solução para que se possa exigir uma variável apenas se um determinado destino for invocado.
$(call check_defined, ...)
de dentro da receitaBasta mover o cheque para a receita:
O
@
sinal principal desativa o eco do comando e:
é o comando real, um esboço de no-op do shell .Mostrando o nome do destino
A
check_defined
função pode ser aprimorada para também gerar o nome do destino (fornecido através da$@
variável):Portanto, agora uma verificação com falha produz uma saída bem formatada:
check-defined-MY_FLAG
alvo especialPessoalmente, eu usaria a solução simples e direta acima. No entanto, por exemplo, esta resposta sugere o uso de um destino especial para executar a verificação real. Pode-se tentar generalizar isso e definir o destino como uma regra padrão implícita:
Uso:
Observe que ele
check-defined-BAR
está listado como pré-requisito somente para pedido (|...
).Prós:
Contras:
make -t
(consulte Em vez de executar receitas ) poluirá seu diretório raiz com muitoscheck-defined-...
arquivos. Essa é uma triste desvantagem do fato de que regras de padrão não podem ser declaradas.PHONY
.Eu acredito que essas limitações podem ser superadas usando um pouco de
eval
magia e truques de expansão secundários , embora não tenha certeza de que vale a pena.fonte
make --version
como o primeiro passo.Use a função shell
test
:Uso:
fonte
checkforsomething
destino que tinha apenas otest
conteúdo efoo
dependente disso; e 2) mudei a verificação para@if test -z "$(something)"; then echo "helpful error here"; exit 1; fi
. Isso me deu a capacidade de adicionar um erro útil e me permitiu tornar o nome do novo destino um pouco mais indicativo do que também deu errado.Makefile:5: *** missing separator. Stop.
test -n "$(something) || (echo "message" ; exit 1)
evitar o explícitoif
.Você pode usar um IF para testar:
Resultado:
fonte
[
é um apelido para o comandotest
, portanto, esta é a mesma resposta que o @Messa acima. Porém, isso é mais compacto e inclui a geração de mensagens de erro.Use o tratamento de erros do shell para variáveis não definidas (observe o dobro
$
):Se você precisar de uma mensagem de erro personalizada, adicione-a após o
?
:fonte
Por simplicidade e brevidade:
Com saídas:
fonte