Ich erhalte einige unerwartete Ergebnisse, wenn ich ein Makefile von einem anderen aufrufe. Ich habe zwei Makefiles, eines mit dem Namen /path/to/project/makefile
und eines mit dem Namen /path/to/project/gtest-1.4.0/make/Makefile
. Ich versuche, den ersteren den letzteren anrufen zu lassen. In / path / to / project / makefile habe ich
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
Und in /path/to/project/gtest-1.4.0/make/Makefile
habe ich
all: $(TESTS)
clean:
rm -f $(TESTS) gtest.a gtest_main.a *.o
Folgendes ausgeben:
cd /path/to/project
make
Ausgänge:
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'
Wenn ich jedoch folgende Befehle erteile:
cd /path/to/project
make clean
Aha:
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'
Ich verstehe nicht: In beiden Fällen /path/to/project/makefile
wird mir mitgeteilt, dass das aktuelle Arbeitsverzeichnis eingegeben wird. Im ersten Fall glaubt es nicht, dass es Arbeit zu erledigen hat (wenn dies der Fall ist), und im zweiten Fall kann es die entsprechende Direktive finden (wenn die Ausgabe mir sagt, dass es im falschen Verzeichnis sucht), versucht es jedoch um den rm
Befehl /path/to/project
anstelle von auszuführen /path/to/makefile/gtest-1.4.0/make/
.
Vermisse ich etwas Grundlegendes, um Makefiles voneinander abzurufen? Habe ich einen ungeheuren konzeptionellen Fehler gemacht oder bin ich auf eine häufige Falle gestoßen? Wie ändere ich effektiv Verzeichnisse und rufe ein zweites Makefile aus dem ersten heraus auf? Mein Verständnis war, dass make -f <name>
es ausreichen würde , einfach anzurufen .
Dies ist make / gmake 3.81 in bash.
make -f gtest-1.4.0/make/Makefile clean
du es besser sagst$(MAKE) -C gtest-1.4.0/make clean
. Warum haben Sie keine falschen Ziele definiert?Antworten:
Ich bin mir nicht ganz sicher, was Sie fragen, aber wenn Sie die
-f
Befehlszeilenoption verwenden, wird nur eine Datei angegeben - es wird nicht angegeben, dass make Verzeichnisse ändern soll. Wenn Sie die Arbeit in einem anderen Verzeichnis erledigen möchten, müssen Siecd
in das Verzeichnis:Beachten Sie, dass jede Zeile in
Makefile
einer separaten Shell ausgeführt wird, sodass das Verzeichnis nicht zurück geändert werden muss.quelle
cd
das Verzeichnis zugtest-1.4.0
wechseln, sollten Sie die-C
Option von verwendenmake
.&&
zwischen der CD und dem Befehl make verwenden. Andernfalls wird die CD, wenn sie ausfällt, immer noch ausgeführtmake clean
... im falschen Verzeichnis !! Außerdem sollten Sie beim Rekursieren immer NUR$(MAKE)
das Barwort verwenden , niemals dasmake
Barwort. Also so etwas wie:cd gtest-1.4.0 && $(MAKE) clean
-C
ist nicht in der Spezifikation-C
ist in der Spezifikation: gnu.org/software/make/manual/make.html#RecursionStatt der
-f
vonmake
möchten Sie vielleicht die verwenden-C <path>
Option. Dies ändert zuerst den Pfad '<path>
' und ruft dannmake
dort auf.Beispiel:
quelle
cd
führen, dass das Terminal in eine Endlosschleife gerät.http://www.gnu.org/software/make/manual/make.html#Recursion
oder äquivalent dazu:
quelle
Es scheint klar zu sein, dass
$(TESTS)
es leer ist, so dass Ihr 1.4.0-Makefile effektiv istIn der Tat hat alles nichts zu tun. und sauber macht genau das, was es sagt
rm -f gtest.a ...
quelle
wildcard
und a definiertpatsubst
, diese werden jedoch aus dem Haupt-Makefile leer zurückgegeben, da das Verzeichnis nicht effektiv geändert wird. Gutes Auge.