Comandos bash multilínea en archivo MAKE

Tengo una manera muy cómoda de comstackr mi proyecto a través de algunas líneas de comandos bash. Pero ahora necesito comstackrlo a través de makefile. Teniendo en cuenta que cada comando se ejecuta en su propio shell, mi pregunta es ¿cuál es la mejor forma de ejecutar el comando bash de varias líneas, depende de cada uno, en el archivo MAKE? Por ejemplo, así:

for i in `find` do all="$all $i" done gcc $all 

Además, ¿alguien puede explicar por qué incluso el comando de una línea bash -c 'a=3; echo $a > file' bash -c 'a=3; echo $a > file' funciona correctamente en la terminal, pero crea un archivo vacío en el caso de makefile?

Yo usaría backslash-newline:

 foo: for i in `find`; \ do \ all="$$all $$i"; \ done; \ gcc $$all 

UPD.

O, en caso de que solo quiera pasar la lista completa devuelta por find a gcc :

 foo: gcc `find` 

Como se indica en la pregunta, cada sub-comando se ejecuta en su propio shell . Esto hace que escribir guiones de shell no triviales sea un poco complicado, ¡ pero es posible! La solución es consolidar su script en lo que make considerará un solo sub comando (una sola línea).

Consejos para escribir scripts de shell en makefiles:

  1. Escape el uso del script de $ reemplazando con $$
  2. Convierta el script para que funcione como una sola línea insertando ; entre comandos
  3. Si desea escribir la secuencia de comandos en varias líneas, escaque al final de la línea con \
  4. Opcionalmente, comience con set -e para que coincida con la provisión de make para abortar la falla del comando secundario
  5. Esto es totalmente opcional, pero puede poner el guión entre corchetes con () o {} para enfatizar la cohesión de una secuencia de múltiples líneas, que esta no es una secuencia típica de comando de archivo

Aquí hay un ejemplo inspirado en el OP:

 mytarget: { \ set -e ;\ msg="header:" ;\ for i in $$(seq 1 3) ; do msg="$$msg pre_$${i}_post" ; done ;\ msg="$$msg :footer" ;\ echo msg=$$msg ;\ } 

Por supuesto, la forma correcta de escribir un Makefile es documentar qué objectives dependen de qué fonts. En el caso trivial, la solución propuesta hará que foo dependa de sí mismo, pero por supuesto, make es lo suficientemente inteligente como para dejar caer una dependencia circular. Pero si agrega un archivo temporal a su directorio, se convertirá “mágicamente” en parte de la cadena de dependencia. Es mejor crear una lista explícita de dependencias de una vez por todas, tal vez a través de un script.

GNU make sabe cómo ejecutar gcc para producir un ejecutable a partir de un conjunto de archivos .c y .h , por lo que tal vez todo lo que realmente necesita equivale a

 foo: $(wildcard *.h) $(wildcard *.c) 

¿Qué pasa con solo invocar los comandos?

 foo: echo line1 echo line2 .... 

Y para su segunda pregunta, necesita escapar de $ usando $$ lugar, es decir, bash -c '... echo $$a ...' .

EDITAR: Su ejemplo podría reescribirse en un solo script de línea como este:

 gcc $(for i in `find`; do echo $i; done)