Reputation: 637
My basic Makefile create the .o without the need of writing a line with gcc:
NAME = libtest.h
CC = gcc
CFLAGS = -I. -c
SRCS = example01.c \
example02.c
OBJ = $(SRCS:.c=.o)
all: $(NAME)
$(NAME): $(OBJ)
ar -rc $@ $<
I suppose that the rule $(SRCS:.c=.o)
is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<
because I didn't need to call for the compiler explicitly?
But then when I try to do the same with the add of a subdirectory in which goes the OBJ files it doesn't work:
NAME = libtest.h
CC = gcc
CFLAGS = -I. -c
SRCS = example01.c \
example02.c
ODIR = ./builds
OBJ = $(addprefix $(ODIR)/, $(SRCS:.c=.o))
all: $(NAME)
$(NAME): $(OBJ)
ar -rc $@ $<
The subdirectory already exist in this example of course. The error output is : No rule to make target 'builds/example01.o', needed by 'libtest.a'
I saw solutions that both explicitly call the compiler and have the rule $(SRCS:.c=.o)
but I feel like it calls for the compiler two times with no need then?
Upvotes: 0
Views: 756
Reputation: 100856
This:
I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<
is not quite right. Make has a suite of built-in pattern rules it can apply if you don't define your own rule. One of these tells it how to build a foo.o
file from a foo.c
file.
But make has no built-in rule telling it how to build a ./builds/foo.o
file from a foo.c
file, so you have to supply that yourself:
$(ODIR)/%.o : %.c
$(COMPILE.c) -o $@ $<
(this uses a built-in variable COMPILE.c
which is what the built-in rule uses; of course you can define your own).
Upvotes: 3