web-dev-qa-db-fra.com

Comment utiliser les variables Shell dans les actions Makefile?

J'ai le suivant dans un Makefile dans le but de recréer ma base de données, y compris de la détruire si nécessaire Ça ne marche pas.

.PHONY: rebuilddb
    exists=$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'")
    if [ $(exists) -eq 1 ]; then
        dropdb the_db
    fi
    createdb -E UTF8 the_db

L'exécuter provoque une erreur:

$ make rebuilddb
exists=
if [  -eq 1 ]; then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [rebuilddb_postgres] Error 2

Pourquoi est-ce faux? Il semble que Bash soit valide, pour autant que je sache? Y a-t-il des considérations spéciales que je dois faire en faisant cela dans un Makefile?

METTRE À JOUR:

En utilisant la réponse, je suis arrivé à une version de travail:

.PHONY: rebuilddb
    exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'"); \
    if [ "$$exists" == "1" ]; then \
        dropdb the_db; \
    fi;
    createdb -E UTF8 the_db
27
hekevintran

Il y a au moins deux considérations. $() fait référence à une variable Make. Vous devez échapper au $ pour effectuer une substitution de commande. De plus, les commandes du shell doivent être sur une seule ligne. Essayer:

exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM \
    pg_database WHERE datname='the_db'"); \
    if [ "$$exists" -eq 1 ]; then \
        dropdb the_db; \
    fi; \
    createdb -E UTF8 the_db

D'un autre côté, il semblerait qu'il serait plus simple d'essayer de toujours supprimer la base de données et de permettre l'échec:

rebuilddb:
    -dropdb the_db  # Leading - instructs make to not abort on error
    createdb -E UTF8 the_db
43
William Pursell

Pour compléter l'utilisation dans $ (eval $ (call ...)

L'utilisation dans les règles de génération dynamique vous devez échapper aux variables du shell avec $$$$.

Voici un exemple qui a été testé avec "GNU Make 4.2.1":

MY_LIBS = a b c

a_objs = a1.o a2.o
b_objs = b1.o b2.o b3.o
c_objs = c1.o c2.o c3.o c4.o

défaut: libs

# function lib_rule (name, objs)

définir lib_rule
lib $ (1) .a: $ (2)
exit 1 | tee make.log; test $$$$ {PIPESTATUS [0]} -eq 0
endef

# générer des règles
$ (foreach L, $ (MY_LIBS), $ (eval $ (appelez règle_lib, $ (L), $ ($ (L) _objs)))))

# appel généré des règles
bibliothèques: $ (patsubst%, lib% .a, $ (MY_LIBS))

# génération d'objet factice
% .o:%. c
touch $ @

# génération de source factice
% .c:
touch $ @

nettoyer::
rm -f * .c * .o lib * .a make.log

La sortie: 'make -rr'

sortie 1 | tee make.log; test $ {PIPESTATUS [0]} -eq 0
make: *** [Makefile: 18: liba.a] Erreur 1

Le résultat de la dernière commande dans le tube est vrai de tee . Vous pouvez voir la variable bash PIPESTATUS [0] a la valeur false from exit 1

Regarder la base de données: 'make -rrp'

définir lib_rule
lib $ (1) .a: $ (2)
exit 1 | tee make.log; test $$$$ {PIPESTATUS [0]} -eq 0
endef

...

libc.a: c1.o c2.o c3.o c4.o
exit 1 | tee make.log; test $$ {PIPESTATUS [0]} -eq 0

0
Clemens1509