bash makefile

Comandos bash multilínea en makefile



(4)

¿Qué hay de malo con solo invocar los comandos?

foo: echo line1 echo line2 ....

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

EDITAR: Su ejemplo podría reescribirse en una sola línea de comandos como esta:

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

Tengo una forma muy cómoda de compilar mi proyecto a través de unas pocas líneas de comandos bash. Pero ahora necesito compilarlo 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 manera de ejecutar el comando de bash multilínea, dependiendo de cada uno, en makefile? Por ejemplo, como este:

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

Además, ¿alguien puede explicar por qué incluso el comando de una sola 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?


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

Consejos para escribir scripts de shell en makefiles:

  1. Escape del uso del script de $ sustituyendo 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, escape de fin de línea con /
  4. Opcionalmente, comience con set -e para que coincida con la provisión de make para abortar en el fallo de un subcomando
  5. Esto es totalmente opcional, pero puede colocar el script entre () o {} para enfatizar la cohesión de una secuencia de múltiples líneas, esto no es una secuencia de comandos de makefile típica

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é objetivos dependen de qué fuentes. En el caso trivial, la solución propuesta hará que foo dependa de sí misma, pero, por supuesto, make sea ​​lo suficientemente inteligente como para eliminar una dependencia circular. Pero si agrega un archivo temporal a su directorio, se convertirá "mágicamente" en parte de la cadena de dependencia. 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 , así que tal vez todo lo que realmente necesitas sea

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


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`