hugogogo
hugogogo

Reputation: 637

put OBJ files in subdirectory in MAKEFILE

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

Answers (1)

MadScientist
MadScientist

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

Related Questions