Un Makefile avec plusieurs exécutables

J’essaie d’écrire un fichier makefile qui utilise des macros pour créer plusieurs exécutables à partir de plusieurs fichiers à la fois. J’ai essayé de chercher dans les réponses précédentes aux questions mais, étant donné que je connais assez bien la programmation en C et que je travaille avec gcc, je n’ai pas trouvé de réponse à ma question.

Voici ce que j’ai jusqu’à présent:

CC=gcc CFLAGS=-I. OBJ = ex1.c ex3.c EXECUTABLE = ex1 ex3 $(EXECUTABLE): $(OBJ) gcc -o $@ $^ $(CFLAGS) clean: rm -f $(EXECUTABLE) 

Je voudrais la ligne

 $(EXECUTABLE): $(OBJ) 

pour créer des exécutables ex1 et ex3 à partir des fichiers ex1.c ex3.c respectivement.

Dans ce cas particulier, où chaque exécutable a un seul fichier source avec l’extension .c , il vous suffit d’un fichier Makefile d’une ligne:

 all: ex1 ex3 

Les règles intégrées par défaut pour make alors fonctionnent déjà:

 $ make cc -O2 -pipe ex1.c -o ex1 cc -O2 -pipe ex3.c -o ex3 

Derrière la scène, make utilise la règle de suffixe unique intégrée obligatoire POSIXly

 .c: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< 

Variez la commande à votre convenance avec make CC=gcc CFLAGS=-O2 LDFLAGS=-s et similaire.

Anecdote du jour: en fait, si vous voulez nommer les cibles lors de l'appel de make , vous pouvez utiliser un object vide ou même exécuter sans aucun Makefile:

 $ make -f /dev/null CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3 gcc -O2 -s ex1.c -o ex1 gcc -O2 -s ex3.c -o ex3 $ rm -f Makefile ex1 ex3 $ make CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3 gcc -O2 -s ex1.c -o ex1 gcc -O2 -s ex3.c -o ex3 

Faire de la magie!

En règle générale, ne réinventez pas la roue (ou les règles), utilisez les règles déjà existantes. Cela simplifie et rend la vie beaucoup. Cela permet aux makefiles petits et sexy d'impressionner les dames avec 🙂

Quelques suggestions (en supposant que vous utilisez GNU make , pas autre chose)

Tout d’abord, lancez une fois make -p , vous comprendrez que ce que les règles internes make est savoir. Cherchez en particulier COMPILE.c et LINK.c

Ensuite, je suggère

  CFLAGS= -g -Wall -I. 

(parce que vous voulez vraiment -g pour le débogage et -Wall pour obtenir la plupart des avertissements)

Et vous n’avez probablement pas besoin

 $(EXECUTABLE): $(OBJ) gcc -o $@ $^ $(CFLAGS) 

Cependant, je suggère d’append avant la plupart des autres règles

 .PHONY: all clean all: $(EXECUTABLES) 

En fait, je Makefile votre Makefile (pour GNU make !) Comme suit

 # file Makefile CC= gcc RM= rm -vf CFLAGS= -Wall -g CPPFLAGS= -I. SRCFILES= ex1.c ex2.c ## or perhaps $(wildcard *.c) OBJFILES= $(patsubst %.c, %.o, $(SRCFILES)) PROGFILES= $(patsubst %.c, %, $(SRCFILES)) .PHONY: all clean all: $(PROGFILES) clean: $(RM) $(OBJFILES) $(PROGFILES) *~ ## eof Makefile 

Rappelez-vous que l’ onglet est un caractère significatif dans Makefile -s (partie d’action des règles ). Dans cette réponse, les lignes commençant par au moins quatre espaces doivent réellement commencer par un caractère de tabulation .

Une fois que tout est débogué, lancez make clean pour tout nettoyer, puis make -j CFLAGS=-O2 all pour make -j CFLAGS=-O2 all comstackr en parallèle avec des optimisations.

Enfin, je vous recommande d’utiliser remake et d’exécuter remake -x pour déboguer un Makefile complexe -s

Bien entendu, je suppose que votre répertoire ne contient que des programmes à fichier unique.

BTW, il existe d’autres programmes de construction. Peut-être que vous pourriez envisager omake

N’oubliez pas d’utiliser un système de contrôle de version tel que git pour vos fichiers source. Il est également temps d’apprendre un tel outil.

Vous êtes proches, mais vous avez besoin d’une règle de modèle:

 $(EXECUTABLE): % : %.c 

Et puis une règle par défaut pour lui permettre de construire à la fois:

 all: $(EXECUTABLE) 

La réponse suivante inclut plusieurs exécutables tels que initier, processus1, processus2, …, processus4.

 LOCAL_INCLUDE=./ all: clean process_first process_second init process_first: gcc -g -o process1 -I$(LOCAL_INCLUDE) process1.c -lzmq -L. -L./. gcc -g -o process2 -I$(LOCAL_INCLUDE) process2.c -lzmq -L. -L./. process_second: gcc -g -o process3 -I$(LOCAL_INCLUDE) process3.c -lzmq -L. -L./. gcc -g -o process4 -I$(LOCAL_INCLUDE) process4.c -lzmq -L. -L./. init: gcc -g -o initiate -I$(LOCAL_INCLUDE) initiate.c -lzmq -lconfig -lpthread -L. -L./. -ldl -lrt clean: rm -rf init_manager.o init_manager rm -rf process1 process2 process3 process4 

REMARQUE: il est recommandé de nettoyer et de toucher tous les fichiers exécutables avant de les créer à nouveau.