Substituição de processos no GNU Makefiles

8

Em um prompt do bash, é possível executar o diff usando pseudo-arquivos:

diff <(echo test) <(echo test)

Adicionando isto como em um Makefile falha:

all:
        diff <(echo test) <(echo test)

O erro (dica: / bin / sh aponta para / bin / bash neste sistema):

/bin/sh: -c: line 0: syntax error near unexpected token '('
/bin/sh: -c: line 0: 'diff <(echo test) <(echo test)'

O que significa, e existe uma maneira de ainda diferenciar duas saídas sem usar arquivos temporários?

    
por Johannes 07.04.2017 / 11:08

1 resposta

15

/bin/sh pode ser bash em seu sistema, mas quando chamado como sh , bash será executado no modo POSIX (como se POSIXLY_CORRECT fosse definido ou tenha sido iniciado com --posix ) .

Neste modo, as substituições de processo não existem.

Soluções:

all:
    command1 >file1
    command2 >file2
    diff file1 file2
    rm -f file1 file2

Alternativa:

all:
    bash -c "diff <(command1) <(command2)"

Ou apenas defina a variável Makefile SHELL as /bin/bash :

SHELL=/bin/bash

Se você quiser portabilidade, escolha a primeira solução. Se estiver OK com uma dependência em bash , escolha o segundo. Se você também não precisa se preocupar com implementações que não sejam do GNU make , use o terceiro.

Em relação à configuração SHELL : O padrão POSIX diz que executáveis em Makefiles devem ser invocados com a função de biblioteca system() C por make . Não é garantido que essa função use a variável de ambiente SHELL (na verdade, isso não é recomendado pelo padrão). O padrão também vale para dizer que configurar a variável Makefile SHELL não deve afetar a variável de ambiente SHELL . Na maioria das implementações de make que eu conheço, no entanto, a variável Makefile SHELL será usada para executar os comandos.

A sugestão em a justificativa para o utilitário make é usar bash -c :

The historical MAKESHELL feature, and related features provided by other make implementations, were omitted. In some implementations it is used to let a user override the shell to be used to run make commands. This was confusing; for a portable make, the shell should be chosen by the makefile writer. Further, a makefile writer cannot require an alternate shell to be used and still consider the makefile portable. While it would be possible to standardize a mechanism for specifying an alternate shell, existing implementations do not agree on such a mechanism, and makefile writers can already invoke an alternate shell by specifying the shell name in the rule for a target; for example:

python -c "foo"

    
por 07.04.2017 / 11:11