Je ne sais pas si ma question est au bon endroit ici, elle concerne essentiellement l'implémentation GNU de Make. Au besoin, je fais confiance à un modo pour la déplacer.

Pour ceux qui ne le savent pas, un submodule dans git, c'est un répertoire dans un repository qui référence une révision particulière d'un autre repository.

Cette propriété d'être un repository à part entière impose de faire un Makefile récursif.
J'aimerais, de plus, que ce Makefile se comporte bien. C'est à dire qu'il recompile le sous-module quand son code a changé, qu'il recompile / relink le programme principal quand une librairie produite par le sous-module a changé.

Voici donc la solution à laquelle je suis arrivé.
On suppose un sous-module dans le répertoire foo qui produit les lib foo/libfoo.a et foo/libgnufoo.a.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FOO_SUBDIR := $(CURDIR)/foo
LDFLAGS := -L$(FOO_SUBDIR)
 
FOO_LIBSFILES := $(FOO_SUBDIR)/libfoo.a $(FOO_SUBDIR)/libgnufoo.a
FOO_LDLIBS := -lfoo -lgnufoo
 
 
.PHONY: all
all: main
 
main: main.c $(FOO_LIBSFILES)
	gcc -o $@ $< $(LDFLAGS) $(FOO_LDLIBS)
 
$(FOO_LIBSFILES): libfoo
	@# Do nothing
 
.PHONY: libfoo
libfoo:
	$(MAKE) -C $(FOO_SUBDIR)
La cible libfoo est marquée .PHONY de manière à toujours faire appel au Makefile du sous-module pour mettre à jour (ou non) les fichiers .a. Puis make devrait détecter si les fichiers .a ont été mis à jour ou non, et recompiler main.c si besoin.

Seulement voilà, sans la commande qui ne fait rien (celle marquée "# Do nothing"), ce Makefile ne marche pas. On dirait que make ne vérifie pas la date les fichiers .a et ne recompile pas immédiatement main.c quand les librairies sont mises à jour. Du coup, le Makefile ci-dessus marche, mais je ne sais pas pourquoi.

Mon hypothèse est que make ne s'attend pas à ce que libfoo.a soit mis à jour par la target libfoo et ne vérifie que la date des fichiers "cible" quand il y a des commandes susceptibles de les mettre à jour. Mais je n'ai trouvé aucune doc là dessus.

Donc voilà, je suis preneur de toute remarque, solution différente ou explication du fonctionnement de celle-ci.


Merci d'avance.