Eu preciso executar algumas regras de criação condicionalmente, apenas se o Python instalado for maior que uma determinada versão (por exemplo, 2.5).
Eu pensei que poderia fazer algo como executar:
python -c 'import sys; print int(sys.version_info >= (2,5))'
e, em seguida, usando a saída ('1' se aprovado, '0' caso contrário) em uma ifeq
declaração make.
Em um script simples do bash shell, é apenas:
MY_VAR=`python -c 'import sys; print int(sys.version_info >= (2,5))'`
mas isso não funciona em um Makefile.
Alguma sugestão? Eu poderia usar qualquer outra solução sensata para conseguir isso.
Respostas:
Use o Make
shell
builtin como emMY_VAR=$(shell echo whatever)
fonte
$
.Embrulhar a tarefa em
eval
está funcionando para mim.fonte
.PHONY always make these targets
é para isso.Aqui está um exemplo um pouco mais complicado com tubulação e atribuição de variáveis na receita:
fonte
PODNAME
nome da implantação:$(eval PODNAME=$(shell sh -c "kubectl get pod -l app=sqlproxy -o jsonpath='{.items[0].metadata.name}'"))
Estou escrevendo uma resposta para aumentar a visibilidade da sintaxe real que resolve o problema. Infelizmente, o que alguém pode considerar trivial pode se tornar uma dor de cabeça muito significativa para quem procura uma resposta simples para uma pergunta razoável.
Coloque o seguinte no arquivo "Makefile".
O comportamento que você gostaria de ver é o seguinte (supondo que você tenha instalado recentemente o python).
Se você copiar e colar o texto acima no Makefile, conseguirá isso? Provavelmente não. Você provavelmente receberá um erro como o relatado aqui:
makefile: 4: *** separador ausente. Pare
Motivo: porque, embora eu tenha usado pessoalmente uma guia genuína, o Stack Overflow (tentando ser útil) converte minha guia em vários espaços. Você, cidadão frustrado da Internet, agora copia isso, pensando que agora tem o mesmo texto que eu usei. O comando make, agora lê os espaços e descobre que o comando "all" está formatado incorretamente. Portanto, copie o texto acima, cole-o e converta o espaço em branco antes de "@echo" em uma guia, e este exemplo deve finalmente funcionar para você.
fonte
Cuidado com receitas como esta
Faz duas coisas erradas. A primeira linha da receita é executada em uma instância de shell separada da segunda linha. Enquanto isso, a variável é perdida. A segunda coisa errada é que
$
não se escapa.Ambos os problemas foram corrigidos e a variável é utilizável. A barra invertida combina as duas linhas para serem executadas em um único shell; portanto, a configuração da variável e a leitura das palavras posteriores da variável funcionam.
Percebo que o post original dizia como obter os resultados de um comando shell em uma variável MAKE, e essa resposta mostra como obtê-lo em uma variável shell. Mas outros leitores podem se beneficiar.
Uma melhoria final, se o consumidor espera que uma "variável de ambiente" seja definida, você precisará exportá-la.
precisaria disso no makefile
Espero que ajude alguém. Em geral, deve-se evitar fazer qualquer trabalho real fora das receitas, porque se alguém usar o makefile com a opção '--dry-run', apenas para ver o que ele fará, não terá efeitos colaterais indesejáveis. Cada
$(shell)
chamada é avaliada em tempo de compilação e algum trabalho real pode ser feito acidentalmente. Melhor deixar o trabalho real, como gerar IDs, para dentro das receitas, quando possível.fonte
Com o GNU Make, você pode usar
shell
eeval
armazenar, executar e atribuir saída de chamadas arbitrárias da linha de comando. A diferença entre o exemplo abaixo e o que:=
é usado é a:=
atribuição uma vez (quando encontrada) e para todos. Variáveis recursivamente expandidas configuradas com=
são um pouco mais "preguiçosas"; as referências a outras variáveis permanecem até que a própria variável seja referenciada e a subsequente expansão recursiva ocorre sempre que a variável é referenciada , o que é desejável para criar "consistentes, exigíveis, trechos". Consulte o manual sobre configuração de variáveis para obter mais informações.fonte
$(SET_ID)
vive dentro de umaif
cláusula que é falsa , ela ainda é chamada .No exemplo abaixo, eu armazenei o caminho da pasta Makefile
LOCAL_PKG_DIR
e, em seguida, uso aLOCAL_PKG_DIR
variável nos destinos.Makefile:
Saída terminal:
fonte