gcc makefile error: "Pas de règle pour faire la cible ..."


356

J'essaie d'utiliser GCC (linux) avec un makefile pour compiler mon projet.

J'obtiens l'erreur suivante qui ne semble pas déchiffrer dans ce contexte:

"No rule to make target 'vertex.cpp', needed by 'vertex.o'.  Stop."

Voici le makefile:

a.out: vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o
    g++ vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o

main.o: main.cpp main.h
    g++ -c main.cpp

vertex.o: vertex.cpp vertex.h
    g++ -c vertex.cpp

edge.o: edge.cpp edge.h
    g++ -c num.cpp

vlist.o: vlist.cpp vlist.h
    g++ -c vlist.cpp

elist.o: elist.cpp elist.h
    g++ -c elist.cpp

vnode.o: vnode.cpp vnode.h
    g++ -c vnode.cpp

enode.o: enode.cpp enode.h
    g++ -c node.cpp

2
Un exemple typique que vous «faites» que le fichier source «n'existe pas» est de réinitialiser la variable VPATH ou SRC par erreur lorsque vous devez y ajouter. Je veux dire usnig VPATH=au lieu de VPATH+=. Cela rend le fichier Makefile ne peut pas voir les fichiers lorsque le fichier est réellement là.
Chan Kim

Réponses:


425

C'est généralement parce que vous n'avez pas de fichier appelé vertex.cppà créer. Regarde ça:

  • ce fichier existe.
  • vous êtes dans le bon répertoire quand vous faites.

A part ça, je n'ai pas grand chose d'autre à suggérer. Vous pourriez peut-être nous donner une liste de répertoires de ce répertoire.


2
Oui, certaines de mes classes n'ont pas de fichiers .cpp, donc elles n'étaient pas là, provoquant l'erreur. Merci.
Meir

4
vous pouvez également obtenir une telle erreur s'il y a des fichiers d'en-tête que vous avez supprimés mais qui sont toujours dans votre Makefile
ady

@par, cela ressemble à une question différente pour moi. Vous obtiendrez probablement plus d'exposition si vous le posez comme une question.
paxdiablo

Assurez-vous également de sauvegarder votre Makefile après l'avoir édité ... C'est ce qui m'a attiré. J'ai fait toutes mes modifications, puis j'ai oublié d'appuyer sur CTRL + S
Tim

80

D'après mon expérience, cette erreur est souvent causée par une faute d' orthographe .

J'ai eu cette erreur aujourd'hui.

make [1]: *** Aucune règle pour rendre la cible maintenaceDialog.cpp', needed bymaintenaceDialog.o '. Arrêtez.

Dans mon cas, l'erreur était simplement une faute d'orthographe. Le mot MAINTENANCE manquait, c'est le troisième N.

Vérifiez également l'orthographe de vos noms de fichiers.


2
La méta- raison , dans ce cas, est due à la liste explicite des relations objet / source / en-tête. Si les nouveaux outils comme SubCons ou CMake ne sont pas au goût, gcc -MT et gnu make patterns peut résoudre ce problème. Voir aussi .
Nathan Kidd

Tu m'as sauvé la journée! Je vous remercie! :)
Sunit Gautam

Dans mon cas, le chemin était faux, ../../src/file.cmais en fait, il l'était../../src/folder/file.c
Rasmi Ranjan Nayak

31

La raison la plus courante de l'impression de ce message est que vous avez oublié d'inclure le répertoire dans lequel réside le fichier source. En conséquence, gcc "pense" que ce fichier n'existe pas.

Vous pouvez ajouter le répertoire à l'aide de l'argument -I à gcc.


14

Dans mon cas, j'avais utilisé des virgules comme des séparateurs. Pour utiliser votre exemple, j'ai fait ceci:

a.out: vertex.o, edge.o, elist.o, main.o, vlist.o, enode.o, vnode.o
    g++ vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o

Le changer à l'équivalent de

a.out: vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o
    g++ vertex.o edge.o elist.o main.o vlist.o enode.o vnode.o

l'a corrigé.


11

Est-ce que c'est exactement ça? N'oubliez pas que la syntaxe Makefile est compatible avec les espaces et nécessite des onglets pour mettre en retrait les commandes sous les actions.


7

Le problème que j'ai trouvé était encore plus stupide que ce que d'autres personnes ont mentionné.

Nos makefiles obtiennent des listes de choses à construire. Quelqu'un a ajouté TheOtherLibraryà l'une des listes, comme indiqué ci-dessous.

LIBRARYDIRS = src/Library
LIBRARYDIRS = src/TheOtherLibrary

Ils auraient dû faire ceci:

LIBRARYDIRS = src/Library
LIBRARYDIRS += src/TheOtherLibrary

S'ils l'avaient fait de la deuxième façon, ils n'auraient pas effacé la Libraryconstruction. Le plus +=est très important.


6

Dans mon cas, cela était dû à une erreur de règle sur plusieurs lignes dans le Makefile. J'avais quelque chose comme:

OBJS-$(CONFIG_OBJ1)            += file1.o file2.o \
                                  file3.o file4.o \
OBJS-$(CONFIG_OBJ2)            += file5.o 
OBJS-$(CONFIG_OBJ3)            += file6.o
...

La barre oblique inversée à la fin de la liste des fichiers dans CONFIG_OBJ1la règle de a provoqué cette erreur. Cela devrait être comme:

OBJS-$(CONFIG_OBJ1)            += file1.o file2.o \
                                  file3.o file4.o
OBJS-$(CONFIG_OBJ2)            += file5.o
...

5

L'une des erreurs fréquentes peut être une faute de frappe dans un autre nom de fichier .

Votre exemple est assez simple, mais ce qui peut parfois confondre, ce sont les messages de makelui - même. Prenons un exemple.

Le contenu de mon dossier est:

$ ls -1
another_file
index.md
makefile

Alors que mes makefilelooks

all: index.html

%.html: %.md wrong_path_to_another_file
    @echo $@ $<

Bien que j'aie index.mdlà où il devrait être et qu'il n'y ait aucune erreur dans le nom de celui-ci, le message de makesera

make: *** No rule to make target `index.html', needed by `all'.  Stop.

Pour être honnête, le message est déroutant . Il dit simplement qu'il n'y a pas de règle. En fait, cela signifie que la règle est erronée, mais en raison de règles génériques (modèle), makeelles ne peuvent pas déterminer la cause exacte du problème.

Modifions makefileun peu, c'est-à-dire remplaçons les modèles par des règles explicites:

index.html: index.md wrong_path_to_another_file

Et maintenant, le message que nous recevrons sera:

make: *** No rule to make target `wrong_path_to_another_file', needed by `index.html'.  Stop.

Miracle! Les conclusions suivantes pourraient être tirées:

  • Les messages de makedépendent des règles et ne pointent pas toujours la racine des problèmes

  • Il pourrait y avoir d'autres problèmes dans votre makefiledifférent de celui spécifié par ce message

Maintenant, nous avons eu l'idée de vérifier d'autres dépendances dans une règle également:

all: index.html

%.html: %.md another_file
    @echo $@ $<

Seulement cela nous fournira le résultat souhaité:

$ make
index.html index.md

3

Dans mon cas, le message d'erreur faisait référence à un ancien nom de fichier, qui n'existait plus car il avait été renommé. Il s'est avéré que les informations obsolètes ne provenaient pas du Makefile, mais de fichiers dans des .depsrépertoires.

J'ai rencontré cette erreur après avoir copié des fichiers d'une machine à une autre. Dans ce processus, je suppose que les horodatages sont entrés dans un état incohérent, ce qui a confondu "make" lors de l'exécution de plusieurs travaux en parallèle (similaire à ce rapport de bogue ).

Les versions séquentielles avec make -j 1n'ont pas été affectées, mais il m'a fallu un certain temps pour m'en rendre compte car j'utilisais un alias ( make -j 8).

Pour nettoyer l'état, j'ai supprimé tous les .depsfichiers et régénéré le Makefile. Ce sont les commandes que j'ai utilisées:

find | grep '.deps' | xargs rm
find | grep '.deps' | xargs rmdir
autoreconf --install # (optional, but my project is using autotools) 
./configure

Après cela, la construction a recommencé.


2

Si vous essayez de construire John the Ripper "bleeding-jumbo" et obtenez une erreur comme "make: *** Pas de règle pour faire la cible 'linux-x86-64'". Essayez plutôt d'exécuter cette commande:./configure && make


0

Dans mon cas, les fichiers source et / ou anciens objets ont été verrouillés (en lecture seule) par un IDE semi-bloqué ou à partir d'un service cloud de sauvegarde qui a cessé de fonctionner correctement. Le redémarrage de tous les programmes et services associés à la structure de dossiers a résolu le problème.


0

Un autre exemple d'un problème étrange et sa solution:

Cette:

target_link_libraries(
    ${PROJECT_NAME}
    ${Poco_LIBRARIES}
    ${Poco_Foundation_LIBRARY}
    ${Poco_Net_LIBRARY}
    ${Poco_Util_LIBRARY}
    )

donne: make[3]: *** No rule to make target '/usr/lib/libPocoFoundationd.so', needed by '../hello_poco/bin/mac/HelloPoco'. Stop.

Mais si je le supprime Poco_LIBRARIESça marche:

target_link_libraries(
    ${PROJECT_NAME}
    ${Poco_Foundation_LIBRARY}
    ${Poco_Net_LIBRARY}
    ${Poco_Util_LIBRARY}
    )

J'utilise clang8 sur Mac et clang 3.9 sur Linux Le problème ne se produit que sur Linux mais fonctionne sur Mac!

J'ai oublié de mentionner: Poco_LIBRARIESétait faux - il n'a pas été défini par cmake / find_package!


0

Dans mon cas, le chemin n'est pas défini dans VPATH, après avoir ajouté l'erreur disparue.


0

Il y a plusieurs raisons à cette erreur.

L'une des raisons pour lesquelles j'ai rencontré cette erreur est lors de la construction pour Linux et Windows.

J'ai un nom de fichier avec des majuscules BaseClass.h SubClass.h Unix maintient une convention de nom de fichier sensible à la casse et Windows est insensible à la casse.

C ++ pourquoi les gens n'utilisent pas de majuscules dans le nom des fichiers d'en-tête?

Essayez de compiler une build propre en utilisant gmake clean si vous utilisez gmake

Certains éditeurs de texte ont des paramètres par défaut pour ignorer les noms de fichiers sensibles à la casse. Cela pourrait également conduire à la même erreur.

comment ajouter un fichier c ++ dans Qt Creator dont le nom commence par des majuscules? Il en fait automatiquement une petite lettre


0

Cette erreur s'est produite pour moi dans Travis lorsque j'ai oublié d'ajouter de nouveaux fichiers à mon référentiel git. Erreur idiote, mais je peux voir que c'est assez courant.


-1

Dans mon cas, c'était parce que j'appelais le Makefile: MAKEFILE (toutes majuscules)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.