Building from different source folders to different target folders - JohnHau/mis GitHub Wiki

image

image

Makefile

Set project directory one level above of Makefile directory. $(CURDIR) is a GNU make variable containing the path to the current working directory

PROJDIR := $(realpath $(CURDIR)/..) SOURCEDIR := $(PROJDIR)/Sources BUILDDIR := $(PROJDIR)/Build

Name of the final executable

TARGET = myApp.exe

Decide whether the commands will be shwon or not

VERBOSE = TRUE

Create the list of directories

DIRS = Folder0 Folder1 Folder2 SOURCEDIRS = $(foreach dir, $(DIRS), $(addprefix $(SOURCEDIR)/, $(dir))) TARGETDIRS = $(foreach dir, $(DIRS), $(addprefix $(BUILDDIR)/, $(dir)))

Generate the GCC includes parameters by adding -I before each source folder

INCLUDES = $(foreach dir, $(SOURCEDIRS), $(addprefix -I, $(dir)))

Add this list to VPATH, the place make will look for the source files

VPATH = $(SOURCEDIRS)

Create a list of *.c sources in DIRS

SOURCES = $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.c))

Define objects for all sources

OBJS := $(subst $(SOURCEDIR),$(BUILDDIR),$(SOURCES:.c=.o))

Define dependencies files for all objects

DEPS = $(OBJS:.o=.d)

Name the compiler

CC = gcc

OS specific part

ifeq ($(OS),Windows_NT) RM = del /F /Q RMDIR = -RMDIR /S /Q MKDIR = -mkdir ERRIGNORE = 2>NUL || true SEP=\ else RM = rm -rf RMDIR = rm -rf MKDIR = mkdir -p ERRIGNORE = 2>/dev/null SEP=/ endif

Remove space after separator

PSEP = $(strip $(SEP))

Hide or not the calls depending of VERBOSE

ifeq ($(VERBOSE),TRUE) HIDE =
else HIDE = @ endif

Define the function that will generate each rule

define generateRules $(1)/%.o: %.c @echo Building $$@ $(HIDE)$(CC) -c $$(INCLUDES) -o $$(subst /,$$(PSEP),$$@) $$(subst /,$$(PSEP),$$<) -MMD endef

.PHONY: all clean directories

all: directories $(TARGET)

$(TARGET): $(OBJS) $(HIDE)echo Linking $@ $(HIDE)$(CC) $(OBJS) -o $(TARGET)

Include dependencies

-include $(DEPS)

Generate rules

$(foreach targetdir, $(TARGETDIRS), $(eval $(call generateRules, $(targetdir))))

directories: $(HIDE)$(MKDIR) $(subst /,$(PSEP),$(TARGETDIRS)) $(ERRIGNORE)

Remove all objects, dependencies and executable files generated during the build

clean: $(HIDE)$(RMDIR) $(subst /,$(PSEP),$(TARGETDIRS)) $(ERRIGNORE) $(HIDE)$(RM) $(TARGET) $(ERRIGNORE) @echo Cleaning done !

image