Ich habe eine Reihe von Verzeichnissen, von denen einige Makefiles enthalten, und einige der Makefiles haben clean
Ziele. 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, one
und two
, enthaltend;
eins / makefile
clean:
-rm *.x
zwei / makefile
clean:
Im zweiten Fall ist "clean" ohne Anweisungen vorhanden. Wenn Sie also "make clean" two
ausfü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.sh
aus 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 one
brauchte 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>clean
etc.? 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, make
hat es kopiert clean.sh > clean
und 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 three
ohne 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 make
dann 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
(odergmake
je nach System) verwendet werden kann, um die Datenbank impliziter Regeln für genau diese Version zu sichern. Hat mir oft geholfen.