Kartik Anand
Kartik Anand

Reputation: 4609

Makefile first rule target

I am trying to learn make using simply three files.

foo.h

#ifndef __foo_H_
#define __foo_H_

void print();

#endif

foo.c

#include <stdio.h>
#include "foo.h"


void print()
{
    printf("Hello World !");
}

main.c

#include "foo.h"

int main()
{
    print();
    return 0;
}

When I use the following makefile, everything runs fine

makefile

CC = gcc
CFLAGS = -I.
DEPS = foo.h
OBJ = foo.o main.o 

.PHONY: clean

main: $(OBJ)
        gcc -o $@ $^ $(CFLAGS)

%.o: %.c $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

clean:
        rm *.o

The above works because make by default runs the first target(Which I read basically everywhere).

If I use the below makefile

CC = gcc
CFLAGS = -I.
DEPS = foo.h
OBJ = foo.o main.o 

.PHONY: clean

clean:
        rm *.o

main: $(OBJ)
        gcc -o $@ $^ $(CFLAGS)

%.o: %.c $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

Calling make on the above makefile runs only make clean because make by default runs the first rule.

The problem is with this makefile

CC = gcc
CFLAGS = -I.
DEPS = foo.h
OBJ = foo.o main.o 

.PHONY: clean

%.o: %.c $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

main: $(OBJ)
        gcc -o $@ $^ $(CFLAGS)

clean:
        rm *.o

In the above makefile using make I get

gcc -c -o foo.o foo.c -I.
gcc -c -o main.o main.c -I.
gcc -o main foo.o main.o -I.

Why doesn't make just build the .o files and stop since it is the first target, why does it go on to build main as well? There is no where that I've specified in the first rule to build main.

Upvotes: 0

Views: 1231

Answers (2)

MadScientist
MadScientist

Reputation: 100856

The "first target" rule only counts explicit targets. It doesn't count implicit targets, such as suffix rules or pattern rules.

Consider: how would make determine that it should build the .o files? Which .o files should it build? How would make understand that it should build the ones in the variable OBJ, versus any other variable?

Upvotes: 5

Etan Reisner
Etan Reisner

Reputation: 80931

I was looking for a good section of the manual to point you at but haven't found anything specific and concrete to use. The answer to the question, as far as I know, is that a pattern rule is not a target and the default target must, as its name indicates, be a target.

Were you using a static pattern rule (which does define targets) then your expectation would almost be correct as make would pick the first such file and build just that in this case (not all as you might expect just the first).

Upvotes: 1

Related Questions