Reputation: 510
I have seen similar questions, but in my case none of the answers given work. I have written the following Makefile:
# Compiler to use
CC = gcc
# flags to pass compiler
CFLAGS = -ggdb3 -O0 -std=c99 -Wall -Werror
# Name for the executable
EXE = cuaterniones
# space-separated list of header files
HDRS = cuaternion.h
# space-separated list of libraries, if any,
# each of which should be prefixed with -l
LIBS = -lm
# space-separated list of source files
SRCS = main.c cuaternion.c
# automatically generated list of object files
OBJS = $(SRCS:.c=.o)
# default target
$(EXE): $(OBJS) $(HDRS) Makefile
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
# dependencies
$(OBJS): $(HDRS) Makefile
# housekeeping
clean:
rm -f *.o
As it can be inferred, I want to remove all object files after compiling. However, when I call make, the program is compiled, but object files are not removed. However, if I do: make clean, it works as expected. The thing is, I have seen that this should be automatic, if I call make it should automatically clean the files for me, and that is what I want. Moreover, I want to know why it is not working, what is my mistake?
Upvotes: 1
Views: 3849
Reputation: 212258
First, it is unusual for make clean
to not also remove the executable, as most people would expect it to do. Perhaps you need a clean-obj
target, or similar. In any case, it is not automatic and you need to call it explicitly. eg.:
$(EXE): $(OBJS) $(HDRS) Makefile
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
$(MAKE) clean
Here $(MAKE)
evaluates to the make command used (usually 'make' but could be 'gmake' or something else). But, as mentioned above, the convention is that make clean
should remove the executable, so you probably want to use a different name for a target that only removes object files.
Upvotes: 3
Reputation: 42114
If you don't say anything, make only strives to make the first target, a.k.a. the default target.
Your clean
target isn't the first target, isn't a dependency of the first target, and isn't a target from the command line, so make isn't instructed to go through it.
You could get it included in the default target by splitting them as such:
default: $(EXE) clean # as a first target
But I wouldn't recommend it, it's not a dependency that makes sense, and it won't work at all if you try to run it in parallel.
I personally would just go for a workflow where I simply don't clean after build unless I specifically need to, in which case I'd likely use a canned make && make clean
command line.
Another aproach would be to have the object files built as implicit intermediate targets—I think GNU make cleans those up automatically.
Upvotes: 2