Sustitución de procesos en GNU Makefiles

Sustitución de procesos en GNU Makefiles

En un símbolo del sistema bash, se pueden ejecutar diferencias utilizando pseudoarchivos:

diff <(echo test) <(echo test)

Agregar esto tal como está en un Makefile falla:

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

El error (pista: /bin/sh apunta a /bin/bash en este sistema):

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

¿Qué significa? ¿Existe alguna manera de diferenciar dos salidas sin utilizar archivos temporales?

Respuesta1

/bin/shpuede estar bashen su sistema, pero cuando se invoque como sh, bashse ejecutará en modo POSIX (como si POSIXLY_CORRECTestuviera definido o se iniciara con --posix).

En este modo, las sustituciones de procesos no existen.

Soluciones:

  1. Utilice archivos temporales explícitos:

    all:
        command1 >tmpfile
        command2 | diff tmpfile -
        rm -f tmpfile
    
  2. Utilice un bash -cscript en línea:

    all:
        bash -c 'diff <(command1) <(command2)'
    
  3. Defina la variable Makefile SHELLcomo /bin/bash(o cualquiera que sea la ruta bashen su sistema):

    SHELL=/bin/bash
    

Si desea portabilidad, opte por la primera solución. Si está de acuerdo con una dependencia de bash, elija la segunda. Si además no necesita preocuparse por makeimplementaciones que no sean GNU, utilice la tercera.


Con respecto a la configuración SHELL: el estándar POSIX dice que los ejecutables en Makefiles deben invocarse con la system()función de la biblioteca C mediante make. No se garantiza que esta función utilice la SHELLvariable de entorno (de hecho, el estándar desaconseja hacerlo). El estándar también va más allá al decir que configurar la variable Makefile SHELLno debería afectar elVariable ambiental SHELL. Sin embargo, en la mayoría de las implementaciones makeque conozco, la variable Makefile SHELLse utilizará para ejecutar los comandos.

La sugerencia enla justificación de la makeutilidades utilizar bash -c:

Se omitieron la característica histórica MAKESHELLy las características relacionadas proporcionadas por otras implementaciones. makeEn algunas implementaciones, se utiliza para permitir que un usuario anule el shell que se utilizará para ejecutar makecomandos. Esto era confuso; para un portátil make, el shell debe ser elegido por el escritor del archivo MAKE. Además, un escritor de archivos MAKE no puede exigir el uso de un shell alternativo y aun así considerar el archivo MAKE portátil. Si bien sería posible estandarizar un mecanismo para especificar un shell alternativo, las implementaciones existentes no están de acuerdo con dicho mecanismo, y los escritores de archivos MAKE ya pueden invocar un shell alternativo especificando el nombre del shell en la regla para un destino; Por ejemplo:

python -c "foo"

información relacionada