Question

I'm trying to write a makefile to build a release or debug version of my program using the same makefile (the version selection will be based on env. variable).

My first try was the following:

PROG  := myProgram

ifdef DEBUG
BUILD := debug
else
BUILD := release
endif

BIN := $(BUILD)/$(PROG)

SRC := main.c

OBJDIR := $(BUILD)/obj/
OBJ    := $(addprefix $(OBJDIR), $(SRC:%.c=%.o))


$(OBJDIR)/%.o: %.c
    $(GCC) $(CFLAGS) -o $@ $<

$(BIN): $(OBJ)
    $(GCC) $(OBJ) -o $@ $(LDFLAGS)

all: $(BIN)

When I try to make my project, I got the following error:

make: *** No rule to make target `release/obj/main.o', needed by `release/myProgram'.  Stop.

When I replaced the rule $(OBJDIR)/%.o by $(BUILD)/obj/%.o, make is able to match the rule and build my objects file.

I am confused: why the first rule is not working? My understanding is make will expand variables in rules before execution, so, in the end, both rules will looks the same?

What is the best practice in this case?

Thanks in advance for your help.

Was it helpful?

Solution

You put in an extra slash:

OBJDIR := $(BUILD)/obj/


$(OBJDIR)/%.o: %.c
    ...

The rule, as written, will match the target release/obj//main.o, but there is no rule that matches release/obj/main.o.

Just remove the offending slash:

OBJDIR := $(BUILD)/obj
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top