No meu GNUmakefile, eu gostaria de ter uma regra que use um diretório temporário. Por exemplo:
out.tar: TMP := $(shell mktemp -d)
echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Conforme escrito, a regra acima cria o diretório temporário no momento em que a regra é analisada . Isso significa que, mesmo eu não entendo.tar o tempo todo, muitos diretórios temporários são criados. Eu gostaria de evitar que meu / tmp esteja repleto de diretórios temporários não utilizados.
Existe uma maneira de fazer com que a variável seja definida apenas quando a regra é acionada, em vez de sempre que é definida?
Meu pensamento principal é despejar o mktemp e o tar em um script de shell, mas isso parece um pouco desagradável.
$(eval $@_TMP := $(shell mktemp -d))
acontecerá quando o Makefile for avaliado pela primeira vez, não na ordem dos procedimentos da regra. Em outras palavras,$(eval ...)
acontece mais cedo do que você pensa. Embora isso possa ser bom para este exemplo, esse método causará problemas para algumas operações seqüenciais.Uma maneira relativamente fácil de fazer isso é escrever a sequência inteira como um script de shell.
Consolidei algumas dicas relacionadas aqui: https://stackoverflow.com/a/29085684/86967
fonte
@
eeval
e fazendo o mesmo trabalho). Observe que em sua saída você vê$TMP
(por exemplotar -C $TMP ...
), embora o valor seja passado corretamente para o comando.SHELL := /bin/bash
em seu makefile ativar recursos específicos do BASH.Outra possibilidade é usar linhas separadas para configurar as variáveis Make quando uma regra é acionada.
Por exemplo, aqui está um makefile com duas regras. Se uma regra for acionada, ela criará um diretório dir e definirá TMP para o nome do diretório temp.
A execução do código produz o resultado esperado:
fonte
ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
eruleB: TMP = $(shell mktemp -d testruleB_XXXX)
acontecerá quando o Makefile for avaliado pela primeira vez. Em outras palavras,ruleA: TMP = $(shell ...
acontece mais cedo do que você pensa. Embora isso possa funcionar para esse caso específico, esse método causará problemas para algumas operações seqüenciais.Não gosto das respostas "Não", mas ... não.
make
As variáveis de são globais e devem ser avaliadas durante o estágio de "análise" do makefile, não durante o estágio de execução.Nesse caso, desde que a variável local para um único destino, siga a resposta do @ nobar e torne-a uma variável shell.
Variáveis específicas de destino também são consideradas prejudiciais por outras implementações do make: kati , Mozilla pymake . Por causa deles, um destino pode ser criado de maneira diferente, dependendo de ser construído de forma independente ou como uma dependência de um destino pai com uma variável específica do destino. E você não saberá como foi , porque não sabe o que já foi construído.
fonte