Newer
Older
WickedDocs / Makefile.inc
#
# Generic Makefile rules that can be included in any Makefile
# Written by John Ryland
# (C) Copyright 2015
#
# Example usage:
#
#     # Example Makefile
#     TARGET        = app_name
#     CONFIG        = debug
#     SOURCES       = main.cpp \
#                     tests.cpp \
#                     file.c
#
#     # Some optional values that can be omitted
#     CFLAGS        = -Os
#     DEFINES       = DEBUG OS_LINUX
#     INCLUDE_PATHS = ./include
#     LIBRARY_PATHS = ./lib
#     LIBRARIES     = utils
#     OBJECTS_DIR   = .obj
#     TARGET_DIR    = ./bin
#
#     # The important part, including the generic set of Makefile rules
#     include ../Makefile.inc
#


#
# Output paths
#
ifeq ($(TARGET_DIR),)
  TARGET_DIR = .
endif
ifeq ($(OBJECTS_DIR),)
  OBJECTS_DIR = .obj
endif

#
# Config
#
ifeq ($(CONFIG),)
  CONFIG = debug
endif
PROGRAM_SUFFIX=_$(CONFIG)
ifeq ($(CONFIG),release)
  PROGRAM_SUFFIX=
endif

#
# Flags
#
CFLAGS_debug      := -g -O0 $(CFLAGS_debug)
CFLAGS_profile    := -pg -DNDEBUG -O5 $(CFLAGS_profile)
CFLAGS_release    := -DNDEBUG -O5 $(CFLAGS_release)
override CFLAGS   :=  $(patsubst %,-I%,$(INCLUDE_PATHS)) $(patsubst %,-D%,$(DEFINES)) $(CFLAGS_$(CONFIG)) $(CFLAGS)
override CXXFLAGS := $(CFLAGS) -std=c++11 $(CXXFLAGS)
override LFLAGS   := $(patsubst %,-L%,$(LIBRARY_PATHS)) $(patsubst %,-l%,$(LIBRARIES)) $(LFLAGS)

#
# Commands
#
CC     = $(TOOLCHAIN_PREFIX)gcc
CXX    = $(TOOLCHAIN_PREFIX)g++
LINK   = $(TOOLCHAIN_PREFIX)g++
MKDIR  = mkdir -p
RM     = rm -f

#
# Targets
#
COMPILED_OBJS  =  $(patsubst   %.c,$(OBJECTS_DIR)/$(CONFIG)/%.o,$(filter   %.c,$(SOURCES)))
COMPILED_OBJS  += $(patsubst %.cpp,$(OBJECTS_DIR)/$(CONFIG)/%.o,$(filter %.cpp,$(SOURCES)))
OBJECTS        += $(COMPILED_OBJS)
# To work out dependancies, one way which is not gcc specific is to just say everything in the include folder is:
# DEPENDS = $(patsubst %,$(INCLUDE_PATH)/%,$(HEADERS))
# But thats not really correct, not every source file depends on everything in the include folder
# Also things may depend on other things outside of include or other source files. A better solution
# for C and C++ code is using gcc -MM option to generate a set of Makefile dependancies we can include (.depend)
DEPENDS = $(OBJECTS_DIR)/.depend
PROGRAM = $(TARGET_DIR)/$(TARGET)$(PROGRAM_SUFFIX)

#
# Rules
#
$(PROGRAM): $(OBJECTS)
	@$(MKDIR) $(dir $@)
	$(LINK) -o $@ $^ $(CXXFLAGS) $(LFLAGS)

$(OBJECTS_DIR)/$(CONFIG)/%.o: %.c $(DEPENDS)
	@$(MKDIR) $(dir $@)
	$(CC) -c -o $@ $< $(CFLAGS)

$(OBJECTS_DIR)/$(CONFIG)/%.o: %.cpp $(DEPENDS)
	@$(MKDIR) $(dir $@)
	$(CXX) -c -o $@ $< $(CXXFLAGS)

$(DEPENDS): $(SOURCES)
	@$(MKDIR) $(dir $@)
	$(CC) $(CFLAGS) -MM $(SOURCES) | sed 's/^\(.*\.o\)/$(OBJECTS_DIR)\/$(CONFIG)\/\1/' > $@

.PHONY: clean
clean:
	$(RM) $(PROGRAM) $(DEPENDS) $(COMPILED_OBJS) core

#
# Dependancies
#
-include $(DEPENDS)