“clean” not working in make file

2020-07-18 10:39发布

问题:

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

回答1:

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


回答2:

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.



回答3:

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]



标签: c++ makefile