This is my make file.
all: observer
observer: main.o weather_center.o display.o subject.o observer.o
g++ main.o weather_center.o display.o subject.o observer.o -o observer
main.o: main.cpp
g++ -c main.cpp
weather_center.o: weather_center.cpp
g++ -c weather_center.cpp
display.o: display.cpp
g++ -c display.cpp
subject.o: subject.cpp
g++ -c subject.cpp
observer.o: observer.cpp
g++ -c observer.cpp
clean:
rm -f *o observer
Here I'm trying to use
clean:
rm -f *o observer
To clean up the temporary *.o files. But program compiles and generate the target assembly, but doesn't delete the *.o files. Not showing any errors also.
- I tried
rm -f *o observer
in terminal. It works fine.
- I have used
Tab
for indent
- there are no files start with
clean
or rm
in the directory.
- tried
$(RM)
instead of rm
. but no lucky
I found the issue. Have to specify clean
as a target of all
otherwise it wont call. generally like this.
all: [your executive names] clean
In above case
all: observer clean
Here is the full make file of above case
all: observer clean
observer: main.o weather_center.o display.o subject.o observer.o
g++ main.o weather_center.o display.o subject.o observer.o -o observer
main.o: main.cpp
g++ -c main.cpp
weather_center.o: weather_center.cpp
g++ -c weather_center.cpp
display.o: display.cpp
g++ -c display.cpp
subject.o: subject.cpp
g++ -c subject.cpp
observer.o: observer.cpp
g++ -c observer.cpp
clean:
rm -f *o observer
As others have mentioned, this is likely an indentation issue. I copied your makefile exactly, touched some dummy .o files and ran it:
$ touch main.o weather_center.o display.o subject.o observer.o
$ make clean
Makefile:4: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
$
After fixing indentation, it seems to work just fine for me:
$ touch main.o weather_center.o display.o subject.o observer.o
$ ls *.o
display.o main.o observer.o subject.o weather_center.o
$ make clean
rm -f *o observer
$ ls *.o
ls: cannot access *.o: No such file or directory
$
The specific indentation fixes I made were:
- target lines should not have any leading whitespace at all
- recipe lines must start with exactly one tab and no other whitespace
E.g:
clean:
rm -f *o observer
I have saved the fixed version here, because stackoverflow messes with tabs/whitespace. Make sure to copy from the RAW Paste Data.
Having read the question, comments and your self-answer in a little more detail, I think there is possibly some explaining to do about conventional usage of make.
You may call the make
executable with a list of targets to build, or no targets at all.
In the case that targets are specified, then make will attempt to build/rebuild those targets. For instance, with the corrected Makefile, make observer
would build the observer
target (observer
executable), make main.o
would simply compile main.cpp to produce main.o, and make clean
would invoke the clean
rule to delete the listed files.
On the other hand, if you invoke make
with no targets, then make will simply use the first target defined in the Makefile as the target that it builds. The convention is that this target is called all
, but it can be called whatever you like. So in the case of the corrected makefile, invoking make
without explicitly passing any targets should result in all
and its dependency observer
being rebuilt. I suspect this is where the confusion has arisen - invoking make
for this makefile with no targets explicitly mentioned should not result in invocation of the clean
target. This is the expected make
behavior.
all: observer clean #1
observer: main.o weather_center.o display.o subject.o observer.o
g++ main.o weather_center.o display.o subject.o observer.o -o observer
main.o: main.cpp
g++ -c main.cpp
weather_center.o: weather_center.cpp
g++ -c weather_center.cpp
display.o: display.cpp
g++ -c display.cpp
subject.o: subject.cpp
g++ -c subject.cpp
observer.o: observer.cpp
g++ -c observer.cpp
clean:
rm -f *.o #2
1 fix all: observer to [all: observer clean]
2 fix rm -f *o observer to [rm -f *.o]