Reputation: 4609
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
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
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