I'm in the process of learning c, and trying to get my head around makefiles. I'm following Learn C the Hard way.
On exercise 2, the extra credit states to make a command in my makefile that allows me to compile my .c file by typing just "make".
My makefile is:
CLAGS=-WALL -g
all: ex1
clean:
rm ex1
This works - i.e. typing make clean removes the ex1 file, and typing make compiles ex1.c into an executable.
However, I'm confused as to why in the clean command, rm ex1 has to be indented on the line below clean, but for the all command, if I indent ex1 on the line below all, it throws an error. Why is this?
My other question is - how exactly does this work? Is all just a keyword that goes along the lines of "when make (with no command) is typed, do this"?
Any help is appreciated.
Thanks.
This:
clean:
rm ex1
is a rule. This rule contains a single command, rm ex1. The command is a shell command. Each command in the rule must be indented with a TAB character (or Make will get confused).
This:
all: ex1
is a rule without commands. The "ex1" here is not a command, it is a prerequisite.
This:
all:
ex1
is an invalid rule, because it contains an invalid command; "ex1" is not a valid shell command. (Just try it on the command line if you don't believe me.)
If you execute Make without specifying a target (by typing "make"), Make will use the default target, which is usually the first target in the makefile. (There are some exceptions you need not worry about now.) By convention, "all" is the name of rule that does most of what you want done, and it is often the default target; this is a convention, not something built into Make.
Because ex1 is a target that defaults to calling cc over a ex1.c file, you could make all: a target like this too
all:
$(CC) -o $(EXECUTABLE) $(CFLAGS) $(LDFLAGS) ex1.c
don't copy and paste this, because i've used spaces and Makefiles require tabs instead.
An even better way would be to create an object files target and compiling only changed files while linking in the other target, like this
CC = gcc
CFLAGS = -Wall -Wextra -Werror
LDFLAGS = # empty if you are not going to link to any library
OBJ = ex1.o
PROGRAM = ex1
all: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROGRAM) $(OBJ)
%.o: %.c
$(CC) $(CFLAGS) -c $<
clean:
rm -fv *.o $(PROGRAM)
now you would easily add more .c files by just appending them to the OBJ macro, like this
OBJ = ex1.o ex2.o ... exn.o
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With