I am trying to create a Makefile to compile my C program. I am trying to generate a Debug and Release build with the following directory structure:
helloworld/
├── Debug/
│ ├── bin/
│ ├── depends/
│ └── obj/
├── Release/
│ ├── bin/
│ ├── depends/
│ └── obj/
├── mylib/
│ ├── bar.c
│ ├── bar.h
│ ├── foo.c
│ └── foo.h
└── main.c
What I want to do is have the Makefile include different dependency files based on the target (Debug vs Release). The makefile I have right now is this:
CC = clang
CFLAGS = -c -g -Wall -Wextra -pedantic
SOURCES = main.c foo.c bar.c
OBJECTS = $(SOURCES:%.c=Debug/obj/%.o)
INCLUDE = -Imylib/
VPATH = mylib
.PHONY: debug
debug: Debug/bin/main
Debug/bin/main: $(OBJECTS)
$(CC) $^ -o -g $@
Debug/obj/%.o: %.c | Debug
$(CC) $(CFLAGS) $< -o $@ -MMD -MP -MF Debug/depends/$(@F:.o=.d) $(INCLUDE)
-include $(SOURCES:%.c=Debug/depends/%.d)
Debug:
-mkdir Debug
-mkdir Debug/bin
-mkdir Debug/depends
-mkdir Debug/obj
clean:
rm -rf Debug
rm -rf Release
Which works great for just debug. But when I try to create separate targets for Debug and Release I'm stumped with how to modify -include $(SOURCES:%.c=Debug/depends/%.d)
CC = clang
CFLAGS = -c -g -Wall -Wextra -pedantic
SOURCES = main.c foo.c bar.c
DEBUG_OBJECTS = $(SOURCES:%.c=Release/obj/%.o)
RELEASE_OBJECTS = $(SOURCES:%.c=Debug/obj/%.o)
INCLUDE = -Imylib/
VPATH = mylib
.PHONY: all debug release
all: release debug
release: Release/bin/main
debug: Debug/bin/main
Release/bin/main: $(RELEASE_OBJECTS)
$(CC) $^ -o $@
Release/obj/%.o: %.c | Release
$(CC) $(CFLAGS) $< -o $@ -MMD -MP -MF Release/depends/$(@F:.o=.d) $(INCLUDE)
Debug/bin/main: $(DEBUG_OBJECTS)
$(CC) $^ -o -g $@
Debug/obj/%.o: %.c | Debug
$(CC) $(CFLAGS) $< -o $@ -MMD -MP -MF Debug/depends/$(@F:.o=.d) $(INCLUDE)
# -------------------------------------------------------
# -include $(SOURCES:%.c=Debug/depends/%.d) What do I do?
# -------------------------------------------------------
Release:
-mkdir Release
-mkdir Release/bin
-mkdir Release/depends
-mkdir Release/obj
Debug:
-mkdir Debug
-mkdir Debug/bin
-mkdir Debug/depends
-mkdir Debug/obj
clean:
rm -rf Debug
rm -rf Release
Questions
How can I conditionally include dependency files based on the target?
Is there a better project organization structure?
I'm extremely new to makefiles. Previously I've just relied on my IDEs to manage building and configurations. Are there any other tips to help improve this makefile?
make debug release
(ormake all
)? Which dependency files shall be included? – Renaud Pacaletmake all
and using justmake debug
andmake release
. – thndrwrks