I have a set of directories, some of which contain makefiles, and some of the makefiles have clean
targets. In the parent directory, I have a simple script:
#!/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
This does a weird thing when it hits a directory with a makefile without a (defined) "clean" target. For example, given two directories, one
and two
, containing;
one/makefile
clean:
-rm *.x
two/makefile
clean:
In the second case "clean" is present without directives, so if you ran "make clean" in two
you'd get:
make: Nothing to be done for `clean'.
Versus if there were no "clean":
make: *** No rule to make target `clean'. Stop.
However, for the problem I'm about to describe, the result is the same whether the target is present but undefined or just not present. Running clean.sh
from the parent directory;
Making clean in one...
rm *.x
rm: cannot remove `*.x': No such file or directory
make: [clean] Error 1 (ignored)
So one
did not need cleaning. No big deal, this is as expected. But then:
Making clean in two...
cat clean.sh >clean
chmod a+x clean
Why the cat clean.sh>clean
etc.? Note I did create a minimal example exactly as shown above -- there are no other files or directories around (just clean.sh, directories one & two, and the very minimal makefiles). But after clean.sh runs, make
has copied clean.sh > clean
and made it executable. If I then run clean.sh again:
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...
Something even weirder, because now it is not using the specified makefiles at all -- it's using some "up to date" mystery target.
I've noticed a perhaps related phenomenon: if remove one of the test clauses in clean.sh like this:
# if [[ -d $f && -f $f/makefile ]]; then
if [[ -d $f ]]; then
And create a directory three
with no makefile, part of the output includes:
Making clean in three...
make: three/makefile: No such file or directory
make: *** No rule to make target `three/makefile'. Stop.
That there is no such file or directory I understand, but why does make
then go on to look for a target with that name? The man page seems pretty straightforward:
-f file, --file=file, --makefile=FILE
Use file as a makefile.