Nayana Adassuriya
Nayana Adassuriya

Reputation: 24766

"clean" not working in make file

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.

Upvotes: 4

Views: 31226

Answers (4)

My Stack Overfloweth
My Stack Overfloweth

Reputation: 4944

In my case (on Windows), I had my make file as the following:

clean:
    rm *.o

When opening the terminal, running this command worked fine for me so I thought it was something with my makefile indentation at first.

Well, I realized the default Windows terminal is actually a powershell window that supports rm *.o. However, the make clean command was opening up a cmd window that did not support the rm command.

My solution ended up turning the clean: portion into something that the cmd for Windows supported. Final result ended up being this:

clean:
    del *.o

Upvotes: 0

beautifularea
beautifularea

Reputation: 47

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]

Upvotes: -1

Digital Trauma
Digital Trauma

Reputation: 15996

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 .

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.

Upvotes: 4

Nayana Adassuriya
Nayana Adassuriya

Reputation: 24766

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

Upvotes: 7

Related Questions