1

yop,


Je me lance dans les Makefile sous l'impulsion de Zephyr (merci à lui, quand je maitriserai ça devrait être super ^^).
J'ai lu plusieurs tutos, dont celui-ci : http://gl.developpez.com/tutoriel/outil/makefile/

Au paragraphe 4 (les règles d'inférence), on lit ceci (entre les deux exemples de Makefile) :
Comme le montre clairement l'exemple précédent, main.o n'est plus reconstruit si hello.h est modifié. Il est possible de préciser les dépendances séparément des règles d'inférence et de rétablir le fonctionnement original, pour obtenir finalement :

Et on voit, dans le second Makefile, que la ligne suivante est rajoutée :
main.o: hello.h

Voici donc le Makefile sur lequel je bosse :
Makefile
CC=gcc
AR=ar
CXXFLAGS=-W -Wall -extra -pedantic -I..\include
LDFLAGS=
EXEC=FLIS.a

SRC= $(wildcard *.cpp)
OBJ= $(SRC:.cpp=.o)


all: $(EXEC)

FLIS.a: $(OBJ)
	$(AR) cr $@ $^
    
Dispatcher.o: CommObject.hpp 
CommObject.o: Dispatcher.hpp

%.o: %.cpp
	$(CC) -o $@ -c $< $(CXXFLAGS)

clean:
	rm *.o

Mon problème principal : quand je lance Make, il me dit ça :
Aucune règle pour fabriquer la cible "CommObject.hpp", nécessaire pour fabriquer Dispatcher.o

Ok, je vois donc bien où le problème se situe. Seulement, pourquoi ne veut-il pas de ça, vu que je crois vraiment avoir fait comme dans le tuto ? Pourquoi n'utilise-t-il pas la règle d'inférence donnée à la ligne du dessous pour fabriquer Dispatcher.o ?

Mon second problème est que clean ne marche pas, mais bon je m'en fous pour le moment, je chercherai un peu plus tard.


Merci d'avance? smile

2

ton commobject.hpp ne doit pas se trouver dans le dossier courant, qui est bien entendu l'endroit ou tous ces fichiers sont recherchés.

sinon, je sais pas.

pour clean, il croit que clean est un fichier.
il faut lui dire que "clean" n'est pas un fichier en ajoutant cette règle comme dépendance de ".PHONY"

.PHONY: clean

#vieuxsouvenirs#

3

Aaaah, ben voilà, je comprends PHONY alors, merci bien, et effectivement truc.hpp n'est pas là. smile

4

Ok, résoudru avec ceci :
- correction des chemins des headers
- utilisation de .PHONY et remplacement de rm par del. Il faut que je vois si je peux installer rm pour MinGW.

Merci bien. smile

5

gcc -o CommObject.o -c CommObject.cpp -W -Wall -extra -pedantic -I../include
gcc -o Dispatcher.o -c Dispatcher.cpp -W -Wall -extra -pedantic -I../include
gcc -o Application.o -c Application.cpp -W -Wall -extra -pedantic -I../include
ar cr FLIS.a CommObject.o Dispatcher.o Application.o

\o/

6

Folco (./4) :
et effectivement truc.hpp n'est pas là.
bah il se disait: tiens truc est pas la donc je dois le rebuilder. Ah bah merde je sais pas comment faire trifus


pour rm: tu peux avoir tout ce qui te manque avec MSYS.

c'est vraiment le pied ce truc, t'as un bash, tous les outils utiles et tu fais de la console linux sous windows.

les C:\chemin sont transformés en /c/chemin

cmd.exe et le reste c'est un peu la misère a coté.

7

Ah ok, j'ai découvert MSYS cet après-midi, j'ai juste regardé de loin, avant de me rendre compte qu'il y avait des montages et des path à régler dans tous les coins :/
On va prendre ça avec des pincettes, mais on va essayer quand même cheeky

Euh attends, pour me fixer un peu les idées, mon makefile, je l'exécute comment ? Je le lance dans un cmd, ou je dois utiliser le shell unix-like (que j'ai dégoté tout à l'heure je sais plus où) et qui fait tourner bash ?

8

bah j'sais pas, tu faisais comment jusqu'à présent? grin je crois que mingw vient avec mingw32-make.exe, qui devrait marcher dans un cmd.

heu, sinon, msys, y'a un setup, et j'ai juste eu à dire ou se trouvait mingw, rien de plus hum

9

comme dit squalyl, pas besoin de t'embêter, mingw32-make (rah, pourquoi ce nom ?!) dans un cmd t'évitera d'avoir à bidouiller des pseudo-shells unix sous Windows et autres hérésies ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

10

Zeph (./10) :
rah, pourquoi ce nom ?!
pour éviter le conflit de nom avec le "make" de msys grin

11

Zeph (./9) :
mingw32-make (rah, pourquoi ce nom ?!)

Clair, si je le lance souvent à la main, je ferai un raccourci plus standard
Zeph (./9) :
dans un cmd t'évitera d'avoir à bidouiller des pseudo-shells unix sous Windows et autres hérésies ^^

Ok très bien. Ca aurait été pour avoir un Makefile compatible Win/Nux sans rien retoucher. Mais c'est pas grave au pire.

Sinon, je compte trouver un moyen sous Notepad++ de lancer un .bat dans un cmd, sans que le cmd se ferme à la fin, avec une simple touche. J'ai pas encore cherché si c'était possible, mais c'est toujours ce que je paramètre dans un IDE.
squalyl (./8) :
bah j'sais pas, tu faisais comment jusqu'à présent?

Dans un cmd, tout simplement, cd <mon projet> && mingw32-make

12

ps -> je haie les softs qui gèrent mal les espaces au parsing. J'ai perdu 1/2 heure à cause d'espaces à la place de tabulations, et d'un espace après un semicolon. Super fin :/

ps2 -> Y a-t-il des macros définies par make pour savoir sur quel OS on se trouve ? genre OSX, WIN32, LINUX ? Non ça n'existe pas ça ?

13

sur windows t'as la variable d'environnement OS qui vaut Windows_NT (voir la commande set) et pas sous linux, sinon à part ça, je crois pas ^^

14

Folco (./11) :
Ok très bien. Ca aurait été pour avoir un Makefile compatible Win/Nux sans rien retoucher. Mais c'est pas grave au pire.

Justement, il le sera, c'est bien là l'intérêt smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

15

Ok, merci. Il faut que j'arrive à me débarasser du del pour le remplacer par un rm et ce sera bon. smile

16

du pseudocode makefile a corriger

avant les règles:

ifeq($OS,Windows_NT)
DELETE=del /y
else
DELETE=rm -f
endif

et dans la règle

$(DELETE) file

je crois...

17

Mais c'est crade, non ? Enfin, j'y ai pensé mais ça m'a paru horrible...

J'ai donc fouillé un peu MSYS, j'ai paramétré %HOME%, C:\MinGW est bien monté comme il faut dans fstab, il me reste une question.
Comment faire pour que rm soit appelé par mingw32-make maintenant ? A partir d'où dois-je lancer tout ce bazard unix pour que rm soit reconnu ? Je dois partir directement du shell de msys ? Donc je dois préciser un autre point de montage dans fstab, genre "d:\programmation\...\monprojet $(HOME)/prog", puis lancer le build à partir du shell de MSYS (msys.bat) ?

18

c'est pas crade, si tu veux juste cmd et mingw32-make t'as pas le choix grin

ouais, sinon, pour avoir rm sous windows, le truc de base c'est à partir du shell msys. dans ce cas rm est dispo partout et t'as pas besoin de del ^^

mais si tes PATH sont bien configurés, les commandes msys peuvent être également lancées depuis cmd grin

parfois sous win je me plante et je fais "ls" au lieu de "dir", et comme msys est dans mon path, ça marche grin

et pas besoin de montage, tu peux directement travailler dans /d/programmation/.../monprojet ^^
les lecteurs windows unixisés n'apparaissent pas dans ls / ^^

19

tromb Fichier joint : k12X (MSYS Make success.PNG)

Merci !!! En fouillant j'en était rendu là où tu me dis dans ton ./18, hormis le fait d'avoir rajouté msys\bin dans %path%, maintenant c'est parfait, tout roule parfaitement, aussi bien le makefile que les commandes unix, et en plus je suis débarassé de mingw32-make \o/


Merci à tous !!! smile

20

21

Quelques remarques :

- utilise g++ à la place de gcc pour faire du C++, ça link automatiquement la lib standard c++ quand tu fais un binaire (là tu n'as qu'une lib statique donc tu ne vois pas le problème)

- du coup, il faut utiliser CXX et non pas CPP (et d'ailleurs c'est CC pour gcc, car CPP c'est le preprocesseur), et ton CXXFLAGS était déjà bon

- à partir de là, la règle implicite %o: %.cpp n'est plus nécessaire car elle est déjà définie par défaut

- ton -I$(INCLUDE) est à mettre dans les CPPFLAGS (pour le preprocesseur) plutôt que CXXFLAGS

- tu peux aussi utiliser $(RM) à la place de 'rm -f', c'est défini par défaut et ton Makefile fonctionnera sur les systèmes où il n'y a pas de rm (ça n'a pas vraiment d'importance, et je ne connais même pas de quels systèmes il s'agit, mais je le précise comme ça quand tu verras $(RM) dans un Makefile tu sauras de quoi il s'agit)

- utilise plutôt "distclean" comme règle, c'est standard

- et enfin, tu peux faire générer les dépendances de tes .o automatiquement par gcc, il suffit de rajouter '-MMD -MP' dans tes CXXFLAGS, ce qui aura pour effet de générer un bout de makefile pour chaque .o avec les dépendances, qu'il ne reste plus qu'à inclure dans ton Makefile :

[code]DEPS=$(OBJ:.o=.d)
-include $(DEPS)[/code]
So much code to write, so little time.

22

Génération automatique des dépendances ??? Le pied, parce qu'à mon avis, c'est le truc génial pour se planter ça, oublier une dépendance \o/

Et ensuite, j'ai lu plusieurs docs et tutos, mais je me mélange beaucoup (comme tu l'as vu) dans les variables prédéfinies, j'avoue être un peu perdu.
Surtout que la doc n'a pas l'air de préciser grand chose : http://www.gnu.org/software/make/manual/make.html#Using-Variables

23

je savais pas que $(RM) était déja défini avec la valeur kivabien pour la plate-forme, c'est cool.

24

Et elle est où, la doc de ces valeurs prédéfinie ?

25

Ok cool !
[google]Makefile predefined variables[/google] => http://www.gnu.org/s/hello/manual/make/Implicit-Variables.html

(ok, les variables prédéfinies sont documentées dans les règles, pas dans les variables, je pouvais chercher grin)

26

nitro (./21) :
- et enfin, tu peux faire générer les dépendances de tes .o automatiquement par gcc, il suffit de rajouter '-MMD -MP' dans tes CXXFLAGS, ce qui aura pour effet de générer un bout de makefile pour chaque .o avec les dépendances

J'en profite pour squatter le topic de Folco tongue

Le switch -M génère effectivement les règles de dépendance, mais pour une raison qui m'échappe il supprime tous les chemins relatifs dans les noms des règles. Du coup un "gcc -MM src/main.c" va sortir quelque chose dans le genre :

main.o: src/main.c src/header.h
Mais perso je place les .o à côté de leurs .c respectifs, et comme la règle s'appelle "main.o" au lieu de "src/main.o", elle ne fonctionne pas. Il y a bien un switch "-MT" qui permet de redéfinir le nom de la règle, mais du coup il faudrait faire un appel à gcc par fichier, ce qui n'est pas spécialement pratique (je ne sais même pas si c'est faisable en Makefile "pur" sans script shell).

Il y a une solution ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

27

28

Zeph (./26) :
Le switch -M génère effectivement les règles de dépendance, mais pour une raison qui m'échappe il supprime tous les chemins relatifs dans les noms des règles. Du coup un "gcc -MM src/main.c" va sortir quelque chose dans le genre :

main.o: src/main.c src/header.h

Il faut utiliser -MD pour générer les .d en effet secondaire de la compilation, c'est comme ça que c'est le plus efficace, et en plus ça marche bien avec les chemins relatifs (je fais exactement comme toi pour le placement des sources et des .o).
So much code to write, so little time.

29

Oui, c'est ce que je viens de faire, mais du coup ça oblige à avoir des tonnes de ".d" partout alors que j'aurais pu avoir un "Makefile.deps" qui contienne l'ensemble des dépendances sad

Ça marche, mais je trouve dommage de ne pas pouvoir éviter de séparer les dépendances. Merci pour la réponse smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

30

Zeph (./29) :
Oui, c'est ce que je viens de faire, mais du coup ça oblige à avoir des tonnes de ".d" partout alors que j'aurais pu avoir un "Makefile.deps" qui contienne l'ensemble des dépendances sad

J'aime pas les .d non plus, du coup j'utilise "-MF $(@D)/.$(@F).d" pour en faire des fichiers cachés, c'est moins moche.
Ça marche, mais je trouve dommage de ne pas pouvoir éviter de séparer les dépendances.

Dans mon cas je ne pourrais pas n'avoir qu'un seul fichier, parce que ça veut dire le regénérer complètement à chaque compilation, et donc reparser tous les fichiers sources. Il se peut que ça soit assez couteux, pour les projets qui contiennent beaucoup de fichiers. L'avantage avec les .d indépendants c'est que ça ne fait que le strict minimum à chaque fois.
So much code to write, so little time.