Baran Kılıç
Baran Kılıç

Reputation: 33

Compile object files into release and debug folders using Makefile

I want to compile my source code and place object files into release and debug folders using make. Is it possible to do it without duplicating rules?

Here is what I tried:

SRCS = a.c b.c c.c
OBJS = $(patsubst %.c,$(BUILD_TYPE)/%.o,$(SRCS))
TARGET = $(BUILD_TYPE)/main

.PHONY: all
all: release

.PHONY: debug
debug: BUILD_TYPE = debug
debug: CFLAGS = -g
debug: $(TARGET)

.PHONY: release
release: BUILD_TYPE = release
release: CFLAGS = -O3
release: $(TARGET)

$(TARGET): $(OBJS)
    $(CC) -o $@ $(OBJS)

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

Edit:

I actually did not want to create the different "main" in the same folder. I wanted them in separate folders. My bad. I changed the example above.

Looks like that there is not a clean way to do this. I need to write multiple rules.

Upvotes: 1

Views: 392

Answers (1)

Beta
Beta

Reputation: 99124

You seem to want this makefile to be able to build two different versions of main, and put them in the same place. The trouble is that ordinarily if Make sees a main, it concludes that main need not be rebuilt, but you might want it rebuilt if you want the other version. Unless you want a mechanism to allow Make to remember which version the extant main is, you must suffer the inefficiency of rebuilding it every time.

First we change the object rule:

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

Then we make lists of the objects:

debug_OBJS=$(patsubst %.c,debug/%.o,$(SRCS))
release_OBJS=$(patsubst %.c,release/%.o,$(SRCS))

Then the main targets:

.PHONY: debug release

debug: CFLAGS = -g
debug: $(debug_OBJS)

release: CFLAGS = -O3
release: $(release_OBJS)

debug release:
    $(CC) -o main $^

Yes, there is still a little bit of redundancy. Yes, it is possible to squeeze it out with some clever coding. But with only two variants, the simple approach is much easier to read and maintain.

Upvotes: 1

Related Questions