Variáveis no GNU Crie receitas, isso é possível?

4

É possível ter variáveis nas receitas do GNU Make?

Algo assim não funciona:

%_t.mkd : %.mkd
    REV=$$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ )
    echo $${REV}

Existe alguma maneira de fazer esse trabalho?

Como você pode ver o que eu quero é extrair a revisão que um arquivo foi alterado e depois usá-lo mais tarde na receita completa. Infelizmente, não posso usar svn:keywords , pois preciso do número de revisão fora do documento em questão.

    
por Magnus 31.07.2014 / 08:49

4 respostas

6

Isso não funciona porque a ferramenta make inicia um novo processo de shell para cada linha de receita. E variáveis de shell - mesmo variáveis de ambiente 'exportadas' - não podem se propagar "para cima"; eles desaparecem assim que o processo do shell termina.

  • O método tradicional é unir as linhas de receita usando \ no Makefile:

    foo: bar baz
        line1; \
        line2; \
        line3
    

    (Observe que os comandos devem ser separados usando ; ou && , porque as barras invertidas também são passadas para o shell que faz a mesma junção de linhas.)

    Veja também info make "Splitting Lines" e info make "Splitting Recipe Lines" no manual GNU Make.

  • O outro método é informar make para sempre usar um processo de shell para toda a receita, usando a diretiva .ONESHELL :

    .ONESHELL:
    
    foo: bar baz
        line1
        line2
        line3
    

    Veja info make "One Shell" .

    (Note que enquanto .ONESHELL é recomendado por POSIX, nem todas as versões suportam ; por exemplo, BSD make only tem um sinalizador de linha de comando para isso. Isso não deve ser um problema.)

por 31.07.2014 / 09:56
4

Graças ao link

Esta é a solução para alterar uma variável em uma receita:

recipe: 
        $(eval variablename=whatever)
    
por 11.10.2016 / 21:54
1

De acordo com Gnu Make 6.5 Setting Variables :

The shell assignment operator != can be used to execute a program and set a variable to its output. This operator first evaluates the right-hand side, then passes that result to the shell for execution. If the result of the execution ends in a newline, that one newline is removed; all other newlines are replaced by spaces. The resulting string is then placed into the named recursively-expanded variable.

Então você pode tentar o seguinte (não testado):

REV != $$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ ) \
echo $${REV}
    
por 31.07.2014 / 09:56
0

pegando o que @ user3645902 mencionou, aqui está a solução para a questão principal:

recipe:
    @$(eval REV='svn info $<|grep 'Last Changed Rev'|cut -f4 -d')
    @echo $(REV)
    
por 15.01.2018 / 16:15

Tags