2010-02-05 6 views
83

Je reçois des résultats inattendus appelant un makefile d'un autre. J'ai deux makefiles, un appelé /path/to/project/makefile et un appelé /path/to/project/gtest-1.4.0/make/Makefile. Je tente d'avoir le premier appel le dernier. Dans/path/to/projet/makefile, jeComment appeler Makefile à partir d'un autre Makefile?

dev: $(OBJ_FILES) 
    $(CPPC) $(LIBS) $(FLAGS_DEV) $(OBJ_FILES) -o $(BIN_DIR)/$(PROJECT) 
    $(MAKE) -f ./gtest-1.4.0/make/Makefile 

clean: 
    rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o 
    rm -f ../svn-commit.tmp~ 
    rm -f $(BIN_DIR)/$(PROJECT) 
    make -f gtest-1.4.0/make/Makefile clean 

Et /path/to/project/gtest-1.4.0/make/Makefile je

all: $(TESTS) 

clean: 
    rm -f $(TESTS) gtest.a gtest_main.a *.o 

émission les éléments suivants:

cd /path/to/project 
make 

Sorties:

make -f ./gtest-1.4.0/make/Makefile 
make[1]: Entering directory `/path/to/project' 
make[1]: Nothing to be done for `all'. 
make[1]: Leaving directory `/path/to/project' 

Cependant, quand je publie ces Commandes:

cd /path/to/project 
make clean 

Je vois:

make -f gtest-1.4.0/make/Makefile clean 
make[1]: Entering directory `/path/to/project' 
rm -f gtest.a gtest_main.a *.o 
make[1]: Leaving directory `/path/to/project' 

Je ne comprends pas: Dans les deux cas, /path/to/project/makefile me dit qu'il est entrer dans le répertoire de travail courant. Dans le premier cas, il ne pense pas qu'il a du travail à faire (quand c'est le cas) et dans le second cas, il est capable de trouver la directive appropriée (quand la sortie me dit qu'il regarde dans le mauvais répertoire) pour exécuter la commande rm dans /path/to/project, au lieu de /path/to/makefile/gtest-1.4.0/make/. Est-ce que je manque quelque chose de fondamental à l'appel de makefiles les uns des autres?

Ai-je commis une erreur conceptuelle flagrante ou atteint un piège commun? Comment puis-je changer efficacement de répertoire et appeler un second makefile depuis le premier? Ma compréhension était que simplement appeler make -f <name> serait suffisant.

C'est make/gmake 3.81 dans bash.

+3

Je pense que, au lieu de 'make -f gtest-1.4.0/faire/Makefile clean' tu ferais mieux de dire '$ (MAKE) -C gtest-1.4.0/make clean'. Pourquoi n'avez-vous pas défini de cibles bidons? –

+0

http://stackoverflow.com/questions/3494999/subdirectories-and-makefiles –

Répondre

81

Je ne comprends pas trop ce que vous demandez, mais l'utilisation de l'option de ligne de commande -f spécifie simplement un fichier - il ne demande pas à make de changer de répertoire. Si vous voulez faire le travail dans un autre répertoire, vous devez cd dans le répertoire:

clean: 
    cd gtest-1.4.0 && $(MAKE) clean 

Notez que chaque ligne Makefile fonctionne dans une coque séparée, donc il n'y a pas besoin de revenir dans le répertoire.

+0

Frapper le clou sur la tête - merci! –

+49

Au lieu de 'cd' 'manuellement dans le répertoire 'gtest-1.4.0', vous devriez utiliser l'option' -C' de 'make'. – Tader

+22

Ou, à tout le moins, vous devez absolument utiliser '&& 'entre la commande cd et make. Sinon, si le cd échoue, il exécutera toujours 'make clean' ... dans le mauvais répertoire !! Aussi, vous devriez toujours utiliser '$ (MAKE)', jamais le bareword 'make', en récursif. Donc quelque chose comme: 'cd gtest-1.4.0 && $ (MAKE) clean' – MadScientist

1

Il semble clair que $(TESTS) est vide si votre 1.4.0 makefile est effectivement

all: 

clean: 
    rm -f gtest.a gtest_main.a *.o 

En effet, tout n'a rien à voir. et nettoie fait exactement ce qu'il dit rm -f gtest.a ...

+0

$ (TESTS) est défini avec un 'wildcard' et un' patsubst', mais ceux-ci sont retournés vides depuis le makefile principal, parce que le répertoire n'est pas modifié de façon efficace. Bon oeil. –

89

Au lieu du -f de make vous pouvez utiliser l'option -C <path>. Ce premier change le chemin '<path>', puis appelle make là.

Exemple:

clean: 
    rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o 
    rm -f ../svn-commit.tmp~ 
    rm -f $(BIN_DIR)/$(PROJECT) 
    $(MAKE) -C gtest-1.4.0/make clean 
+0

Cette voie semble être la meilleure. Viennent des autres réponses qui utilisent 'cd' pour que le terminal entre dans une boucle infinie. – gbmhunter