web-dev-qa-db-fra.com

GNU make yields "les commandes commencent avant la première cible" erreur

Dans mon makefile, je voudrais vérifier l'existence d'une bibliothèque et donner un message d'erreur informatif. J'ai créé un conditionnel qui devrait quitter le processus de création lorsque le fichier n'est pas trouvé:

 9: ifeq ($(${JSONLIBPATH}),)
10:    JSONLIBPATH = ${ALTJSONLIBDIR}/${LIBJSON}
11: endif
12: ifeq ($(${JSONLIBPATH}),)
13:    $(error JSON library is not found. Please install libjson before building)
14: endif 

Mon makefile est bloqué sur la ligne 13:

Makefile:13: *** commands commence before first target.  Stop.

Après la ligne 13, mon makefile a ses cibles.

J'ai essayé de mettre ce bloc conditionnel dans une cible (par exemple une cible appelée isJSONLibraryInstalled) mais cela ne s'exécute pas correctement.

Comment puis-je vérifier l'existence d'un fichier et gérer le cas d'erreur, avant de traiter les cibles? Toutes mes excuses si c'est une question stupide.

49
Alex Reynolds

Tout d'abord, vous regardez le contenu d'une variable nommée d'après le chemin actuel, ce qui n'est probablement pas ce que vous voulez. Une référence de variable d'environnement simple est $(name) ou ${name}, Pas $(${name}). Pour cette raison, la ligne 13 est toujours évaluée.

Deuxièmement, je pense que cela étouffe l'indentation de l'expression $(error ...). Alors que l'expression se résout en une chaîne vide, il y a toujours un caractère de tabulation au début de la ligne, qui indique une commande, qui à son tour ne peut pas exister en dehors d'une règle.

Je pense que l'utilisation d'espaces plutôt que de tabulations pour mettre en retrait fonctionnerait.

75
Simon Richter

Lorsque vous obtenez des messages d'erreur Make, vérifiez toujours le Documentation des messages d'erreur

Sur GNU Make 3.81 (error semble avoir été supprimé des versions plus récentes), il dit:

Cela signifie que la première chose dans le makefile semble faire partie d'un script de commande: il commence par un caractère TAB et ne semble pas être une commande make légale (comme une affectation de variable). Les scripts de commande doivent toujours être associés à une cible.

Ce qui rend les choses plus confuses, c'est que la partie "ne semble pas être une commande légale". Cela explique pourquoi dans:

    a := b
    $(error a)

l'erreur se produit à la ligne 2 et non à 1: make accepte simplement les instructions qu'il peut analyser, comme l'affectation, donc les opérations suivantes fonctionnent:

    a := b
a:
    echo $a

Remarque: SO convertit actuellement les tabulations en espaces dans le code , vous ne pouvez donc pas simplement copier le code ci-dessus dans votre éditeur.

Pour moi, c'était un espace blanc inutile devant le connecteur qui causait cela. Sur slickEdit, j'ai sélectionné l'option pour afficher tous les caractères spéciaux et j'ai remarqué le mouton noir.

1
RobGajula