Erreur «Aucune cible» lors de l'utilisation de Make

12

J'apprends à utiliser makeet à créer des fichiers, j'ai donc écrit ce petit fichier:

%.markdown: %.html
    pandoc -o $< $@

Mais quand je cours make, tout ce que je reçois, c'est make: *** No targets. Stop.ce qui se passe?

ahmed
la source
Sont ces espaces ou un onglet devant la pandoccommande. Make est notoirement pointilleux sur ceux qui sont un onglet et non des espaces.
slm
@slm: c'est un onglet. J'ai lu quelque part que l'EOL de Windows n'est pas compatible, j'ai donc converti le fichier entier en EOL compatible Unix.
ahmed

Réponses:

17

Problème:

Votre problème est qu'il makene connaît pas vos cibles.

Vous pouvez exécuter votre Makefile ci-dessus avec make stackoverflow.markdownpar exemple et cela fonctionnera.

make seulement, cependant, échouera, puisque vous avez seulement spécifié comment créer vos cibles, mais pas lesquelles.

Comme le fait remarquer leiaz, la règle de modèle ci-dessus est appelée une règle implicite .

Makefile:

SRC = $(wildcard *.html)
TAR = $(SRC:.html=.markdown)

.PHONY: all clean

all: $(TAR)

%.markdown: %.html
    pandoc -o $< $@

clean:
    rm -f $(TAR)

Explication:

SRCget tous les fichiers sources (ceux se terminant par .html) via Makefile wildcard.

TAR remplace chaque fichier source répertorié par SRCpar une cible se terminant par .markdownau lieu de .html.

.PHONY répertorie les cibles non physiques qui sont toujours obsolètes et sont donc toujours exécutées - ce sont souvent allet clean.

La cibleall a comme dépendance (les fichiers répertoriés sur le côté droit de :) tous les *.markdownfichiers. Cela signifie que toutes ces cibles sont exécutées.

%.markdown: %.html
    pandoc -o $< $@

Cet extrait indique: Chaque cible se terminant par .markdowndépend d'un fichier du même nom, sauf que la dépendance se termine par .html. Le caractère générique% doit être vu comme un *shell similaire. Le %côté droit, cependant, est comparé au match du côté gauche. Source .

Notez que la séquence d'espaces devant pandocest un TAB, car makedéfinit cela comme une norme.

Enfin, la cleancible bidon décrit comment nettoyer votre système des fichiers que vous avez créés avec ce Makefile. Dans ce cas, il supprime toutes les cibles (les fichiers qui ont été nommés *.markdown.

polym
la source
1
Excellente réponse et ce sont d'autres liens que j'ai trouvés en essayant de mieux le comprendre: fonction générique , références de substitution et cibles bidon .
ahmed
Une autre question s'il vous plaît: peut makefilecréer des fichiers à partir de zéro ou ne met-il à jour que les fichiers existants? Parce que lorsque je supprime les fichiers générés, cela cesse de fonctionner. Question idiote je sais, mais c'est Terre-Neuve pour moi ^^ "
ahmed
1
vous voulez dire s'il n'y a pas de fichiers .markdown, alors ils seront créés? oui, il devrait le faire pour autant que je sache
polym
1
Très bien alors. Je vais creuser un peu plus. Merci pour vos réponses, grâce à vous je suis sur la bonne voie maintenant
:)
1
Je voulais juste vous remercier pour la bonne réponse. La façon dont vous avez expliqué est très facile de comprendre la raison pour laquelle la commande ne fonctionnait pas et des instructions très détaillées sur la façon de procéder. Merci encore.
zanona
5

Les règles de modèle sont des règles implicites.

Vous n'avez aucun objectif défini dans votre Makefile. Vous pouvez spécifier la cible sur la ligne de commande: make something.markdownutilisera la recette pour créer à something.markdownpartir de something.html.

Ou vous pouvez ajouter à votre Makefile une règle spécifiant des cibles par défaut.

all: file1.markdown file2.markdown

Ou avec un caractère générique:

all: *.markdown

Lorsque vous exécutez simplement make, la première cible de la première règle est l'objectif par défaut . Il n'a pas besoin d'être appelé all.

Donc, ci-dessus, la cible alla tous les fichiers que vous souhaitez créer comme prérequis, donc quand vous make all, elle créera tous les fichiers répertoriés.

Leiaz
la source