Erreur dans le fichier makefile (“pas de fichiers d’entrée”)

C’est la première fois que je crée un fichier makefile, et j’essaie vraiment de comprendre le processus.

J’essaie de créer un fichier Make très simple pour un projet C ++ dont la structure est la suivante:

dossier racine
makefile
readme
dossier src
… les fichiers sources tous ici …
dossier d’inclusion
… les fichiers d’en-tête pour les bibliothèques externes ici …
dossier lib
… des fichiers de librairie externes tous ici …
dossier bin
… répertoire de sortie pour l’exécutable construit …
dossier obj
… les fichiers object tous ici …

J’ai suivi le tutoriel ici .

Voici mon makefile:

IDIR=include . CC=g++ CFLAGS=-I$(IDIR) ODIR=bin/obj LDIR=lib LIBS=none SRC=src _DEPS=hello.h DEPS=$(patsubst %,$(IDIR)/,%(_DEPS)) _OBJ=file1.o file2.o OBJ=$(patsubst %,$(ODIR)/%,$(_OBJ)) $(ODIR)/%.o: $(SRC)/%.cpp $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) # $(LIBS) test_proj: $(OBJ) $(CC) -o $@ $^ $(CFLAGS) .PHONY: clean clean: rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

Lorsque je lance make sur ceci, j’obtiens l’erreur suivante:

 g++ -o .o g++: fatal error: no input files compilation terminated. : recipe for target '.o' failed mingw32-make.exe: *** [.o] Error 1 

J’utilise GNU Make 3.82.90 construit pour i686-pc-mingw32, si cela compte vraiment.

Quelqu’un peut-il signaler une erreur ridicule que je commets?

 IDIR=include . 

est le premier problème. Remplacez-le par:

 IDIR=include 

Avec votre code, CFLAGS est développé comme CFLAGS :

 -Iinclude . 

Cela n’a pas de sens, j’ai bien peur. Le deuxième problème est:

 DEPS=$(patsubst %,$(IDIR)/,%(_DEPS)) 

qui devrait probablement être:

 DEPS=$(patsubst %,$(IDIR)/%,$(_DEPS)) 

et se développerait comme:

 DEPS=include/hello.h 

si vous résolvez le premier problème, sinon comme:

 DEPS=include ./hello.h 

ce qui n’a pas de sens non plus. L’effet cumulé de ces deux erreurs sont des recettes étranges (je n’ai pas essayé de les développer à la main) qui déclenchent probablement une règle de création implicite avec de mauvais parameters.

 IDIR=include . CC=g++ CFLAGS=-I$(IDIR) 

C’est faux. Premièrement, pour le code C ++, utilisez CXX non CC et CXXFLAGS et non CFLAGS . Exécutez make -p pour comprendre les règles internes de votre make .

Alors -I$(IDIR) ne “dissortingbue” pas le -I , et IDIR n’est jamais utilisé ailleurs. Je suggère donc de commencer votre Makefile avec:

 CXX=g++ MY_CXX_LANG_FLAGS= -std=c++11 MY_CXX_WARN_FLAGS= -Wall -Wextra MY_CXX_INCL_FLAGS= -I. -Iinclude MY_CXX_MACRO_FLAGS= -DMYFOO=32 ### replace with -O2 for a release build below MY_CXX_OPTIM_FLAGS= -g CXXFLAGS= $(MY_CXX_LANG_FLAGS) $(MY_CXX_WARN_FLAGS) \ $(MY_CXX_INCL_FLAGS) $(MY_CXX_MACRO_FLAGS) 

Je n’améliorerai pas votre Makefile , mais je suggère si possible de mettre à jour GNU make version 4 (et comstackr make 4.1 à partir de son code source en vaut la peine en 2015) à cette fin. Si possible, activez le script GUILE dans celui-ci.

Si vous êtes obligé d’utiliser make 3.82, corrigez votre Makefile avec remake (avec -x ); si vous pouvez vous permettre une version 4 de make utilisez son option --trace

En passant, vous pouvez envisager d’utiliser des dépendances automatiques, c’est-à-dire de générer des dépendances en passant des -MG -M ou -MG (etc.) de g++ .

Enfin, un simple projet pour un petit programme (moins de cent milliers de lignes sources) pourrait simplement mettre tous ses fichiers (quelques dizaines) dans le répertoire courant (le Makefile pourrait alors être plus simple); la structure de répertoires que vous proposez peut être mystérieuse pour un projet simple (mais cela en vaut la peine si vous avez des millions de lignes de code source C ++). J’ai donné plusieurs exemples simples de Makefile , par exemple ceci et cela . Et GNU make code source lui-même a une arborescence de fichiers moins complexe que ce que vous voulez.

BTW, je suis fortement en désaccord avec les opinions de cette réponse (que j’ai voté, car c’est utile). Je ne pense pas que make de GNU soit sénile, mais je regrette qu’au lieu d’utiliser les fonctionnalités récentes disponibles dans les versions récentes (4.x) de make , beaucoup de gens préfèrent utiliser des générateurs de Makefile complexes et mystérieux (comme cmake ) au lieu de coder un Makefile intelligent (pour make version 4 en particulier).

Enfin, vous pouvez utiliser d’autres constructeurs, par exemple omake , icmake , ….