Aman Deep Gautam
Aman Deep Gautam

Reputation: 8787

Understanding a makefile

I am talking about this question where the person has updated his final solution with a makefile for the task. I am having a hard time understanding how it's done.

There is a rule:

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    @$(CC) $(CFLAGS) -c $< -o $@

which I am unable to understand, but by intuition I know what it will be doing. Almost everything else is pretty much clear. Thanks!

Upvotes: 2

Views: 904

Answers (2)

Beta
Beta

Reputation: 99172

This is a static pattern rule. The first field is a list of targets, the second is a target pattern which Make uses to isolate a target's "stem", the third is the prerequisite pattern which Make uses to construct the list of prerequisites.

Suppose you have

SRCDIR = src
OBJDIR = obj
OBJECTS = obj/foo.o obj/bar.o obj/baz.o

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    @$(CC) $(CFLAGS) -c $< -o $@

If you make obj/foo.o, Make first identifies this rule as the one to use (since obj/foo.o is in the target list $(OBJECTS)), matches it against the target pattern obj/%.o and finds that the stem (the part matched by the wildcard %) is foo, then plugs that into the prereq pattern src/%.c and finds that the prerequisite is src/foo.c.

If you've also defined the variables

CC = gcc
CFLAGS = -thisflag -thatflag=something

Then the command in the rule becomes

    @gcc -thisflag -thatflag=something -c src/foo.c -o obj/foo.o

(Note that $< is the first prerequisite and $@ is the target name.)

In answer to your other question: Yes, a makefile can handle a dependency on a header file (x.h) so that if the header has been modified, Make will rebuild the target. No, this makefile doesn't do that. You can modify the makefile by hand, adding rules like

a.o: x.h

assuming you know what the inclusions actually are, or you can have the makefile do it automatically, which is an advanced technique you probably shouldn't attempt yet.

Upvotes: 3

BlueTrin
BlueTrin

Reputation: 10113

This line is explaining how to obtain the object files (.o) from the source (.c), it avoids having to repeat the line for each .c file.

The objects will be in OBJDIR and the sources in SRCDIR

$(CC) will contain the compiler, CFLAGS will contain the options for the compiler and -c tells gcc to compile the source into objects.

For example:

  • CC = gcc

  • CFLAGS = -g -Wall

can be converted into gcc -g -Wall -c test.c -o test.o

Upvotes: 1

Related Questions