Ich habe eine Reihe von Verzeichnissen, von denen einige Makefiles enthalten, und einige der Makefiles haben cleanZiele. Im übergeordneten Verzeichnis habe ich ein einfaches Skript:
#!/bin/bash
for f in *; do
if [[ -d $f && -f $f/makefile ]]; then
echo "Making clean in $f..."
make -f $f/makefile clean
fi
done
Dies macht eine seltsame Sache, wenn es ein Verzeichnis mit einem Makefile ohne ein (definiertes) "sauberes" Ziel trifft. Zum Beispiel gegeben zwei Verzeichnisse, oneund two, enthaltend;
eins / makefile
clean:
-rm *.x
zwei / makefile
clean:
Im zweiten Fall ist "clean" ohne Anweisungen vorhanden. Wenn Sie also "make clean" twoausführen, erhalten Sie:
make: Nothing to be done for `clean'.
Versus wenn es kein "sauberes" gäbe:
make: *** No rule to make target `clean'. Stop.
Für das Problem, das ich beschreiben werde, ist das Ergebnis jedoch dasselbe, unabhängig davon, ob das Ziel vorhanden, aber undefiniert oder einfach nicht vorhanden ist. Wird clean.shaus dem übergeordneten Verzeichnis ausgeführt.
Making clean in one...
rm *.x
rm: cannot remove `*.x': No such file or directory
make: [clean] Error 1 (ignored)
Also onebrauchte ich keine Reinigung. Keine große Sache, das ist wie erwartet. Aber dann:
Making clean in two...
cat clean.sh >clean
chmod a+x clean
Warum die cat clean.sh>cleanetc.? Hinweis: Ich habe genau wie oben gezeigt ein minimales Beispiel erstellt - es gibt keine anderen Dateien oder Verzeichnisse (nur clean.sh, die Verzeichnisse eins und zwei und die sehr minimalen Makefiles). Aber nachdem clean.sh ausgeführt wurde, makehat es kopiert clean.sh > cleanund ausführbar gemacht. Wenn ich dann wieder clean.sh laufen lasse:
Making clean in one...
make: `clean' is up to date.
Making clean in two...
make: `clean' is up to date.
Press any key to continue...
Noch seltsamer, weil jetzt überhaupt nicht die angegebenen Makefiles verwendet werden - es wird ein "aktuelles" Mystery-Ziel verwendet.
Ich habe ein möglicherweise verwandtes Phänomen festgestellt: Wenn Sie eine der Testklauseln in clean.sh wie folgt entfernen:
# if [[ -d $f && -f $f/makefile ]]; then
if [[ -d $f ]]; then
Und erstellen Sie ein Verzeichnis threeohne Makefile. Ein Teil der Ausgabe umfasst:
Making clean in three...
make: three/makefile: No such file or directory
make: *** No rule to make target `three/makefile'. Stop.
Dass es keine solche Datei oder kein solches Verzeichnis gibt, verstehe ich, aber warum sucht er makedann nach einem Ziel mit diesem Namen? Die Manpage scheint ziemlich einfach zu sein:
-f Datei, --file = Datei, --makefile = DATEI
Use file as a makefile.
make -npf /dev/null(odergmakeje nach System) verwendet werden kann, um die Datenbank impliziter Regeln für genau diese Version zu sichern. Hat mir oft geholfen.