user3207575
user3207575

Reputation: 45

Makefile does not make all targets

I am trying to have the compiled obj files in two different folder

  1. dobjects: where the objects have the debug symbol (gcc with -g option)
  2. sobjects: where the objects are compiled without the debug symbols.

Source files are the same,

I have the following makefile.

CC = gcc
CFLAGS = -Wall
OBJS = a.o b.o
SRCS = a.c b.c
SOBJS_DIR = sobjects
DOBJS_DIR = dobjects
SOBJS = $(addprefix $(SOBJS_DIR)/, $(OBJS))
DOBJS = $(addprefix $(DOBJS_DIR)/, $(OBJS))

all: release debug

release: $(SOBJS)

debug: $(DOBJS)

$(DOBJS_DIR)/%.o: CFLAGS += -g

$(DOBJS_DIR)/%.o $(SOBJS_DIR)/%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm dobjects/*
    rm sobjects/*

But every time I try "make" only one target is made.

$ make
gcc -Wall -c a.c -o sobjects/a.o
gcc -Wall -c b.c -o sobjects/b.o

$ make
gcc -Wall -g -c a.c -o dobjects/a.o
gcc -Wall -g -c b.c -o dobjects/b.o

any help would be greatly appreciated

Upvotes: 1

Views: 1229

Answers (1)

MadScientist
MadScientist

Reputation: 101081

This rule does not do what you think it does:

$(DOBJS_DIR)/%.o $(SOBJS_DIR)/%.o: %.c
         $(CC) $(CFLAGS) -c $< -o $@

Pattern rules with multiple targets tell make that one single invocation of the recipe will build BOTH targets. So when make runs that rule to build $(DOBJS_DIR)/a.o, make believes that $(SOBJS_DIR)/a.o was also built, so it doesn't try to run the rule to build it. But your rule doesn't actually build it, so when you run make a second time it sees that object file is missing and runs the above rule again, to build the missing one.

You have to write this as two different rules:

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

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

Upvotes: 4

Related Questions