Commandes de bash multilignes dans makefile

J’ai un moyen très confortable de comstackr mon projet via quelques lignes de commandes bash. Mais maintenant, je dois le comstackr via makefile. Étant donné que chaque commande est exécutée dans son propre shell, ma question est la suivante: quelle est la meilleure façon d’exécuter la commande multi-line bash, dépend l’un de l’autre, dans makefile? Par exemple, comme ceci:

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

En outre, quelqu’un peut-il expliquer pourquoi même la commande de ligne simple bash -c 'a=3; echo $a > file' bash -c 'a=3; echo $a > file' fonctionne correctement dans le terminal, mais crée un fichier vide dans le dossier makefile?

Je voudrais utiliser backslash-newline:

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

UPD.

Ou, si vous voulez juste passer la liste entière retournée par find à gcc :

 foo: gcc `find` 

Comme indiqué dans la question, chaque sous-commande est exécutée dans son propre shell . Cela rend l’écriture de scripts shell non sortingviaux un peu désordonnés – mais c’est possible! La solution consiste à consolider votre script dans la marque qui prendra en compte une seule sous-commande (une seule ligne).

Astuces pour écrire des scripts shell dans les makefiles:

  1. Échappez à l’utilisation du script $ en remplaçant par $$
  2. Convertir le script pour travailler en une seule ligne en insérant ; entre les commandes
  3. Si vous souhaitez écrire le script sur plusieurs lignes, échappez à la fin de la ligne avec \
  4. Commencez éventuellement par set -e pour faire correspondre la disposition de make à un échec de sous-commande
  5. Ceci est totalement optionnel, mais vous pouvez mettre le script entre parenthèses avec () ou {} pour souligner la cohérence d’une séquence de lignes multiples – il ne s’agit pas d’une séquence de commandes typique de makefile

Voici un exemple inspiré par l’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 ;\ } 

Bien sûr, la méthode appropriée pour écrire un fichier Makefile consiste à documenter réellement les cibles qui dépendent des sources. Dans le cas sortingvial, la solution proposée fera que foo dépendra d’elle-même, mais bien sûr, make est assez intelligent pour supprimer une dépendance circulaire. Mais si vous ajoutez un fichier temporaire à votre répertoire, celui-ci fera “magiquement” partie de la chaîne de dépendance. Mieux vaut créer une liste explicite de dépendances une fois pour toutes, peut-être via un script.

GNU make sait comment lancer gcc pour produire un exécutable à partir d’un ensemble de fichiers .h et .h .c

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

Quel est le problème avec juste invoquer les commandes?

 foo: echo line1 echo line2 .... 

Et pour votre deuxième question, vous devez échapper à $ en utilisant $$ place, par exemple bash -c '... echo $$a ...' .

EDIT: Votre exemple pourrait être réécrit en un seul script de ligne comme ceci:

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