Skip to content

Instantly share code, notes, and snippets.

@polyfloyd
Last active August 21, 2017 12:35
Show Gist options
  • Select an option

  • Save polyfloyd/72b297fc88ad5bbb1cc14069eb3130fc to your computer and use it in GitHub Desktop.

Select an option

Save polyfloyd/72b297fc88ad5bbb1cc14069eb3130fc to your computer and use it in GitHub Desktop.
Advanced C++ Makefile
# Environment checks {{{
ifdef VERBOSE
Q :=
E := @true
else
Q := @
E := @echo
# Output coloring {{{
ifndef NOCOLOR
COLOR_COMPILE := \x1b[32;1m
COLOR_LINK := \x1b[36;1m
COLOR_DEP := \x1b[33;1m
COLOR_LOCALE := \x1b[34;1m
COLOR_TOOL := \x1b[35;1m
COLOR_RESET := \x1b[0m
E := @/bin/echo -e
endif
# }}}
endif
# }}}
# Package metadata {{{
PACKAGE_NAME := myproject
PACKAGE_VERSION := $(shell git describe --always --dirty)
ifndef PACKAGE_VERSION
PACKAGE_VERSION := 9999
endif
# }}}
# Directories {{{
SRCDIR := src
OBJDIR := obj
BINDIR := bin
DEPDIR := dep
# }}}
# Output files {{{
BINFILE := $(BINDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
# }}}
# Toolkit selection {{{
CXX := clang++
# }}}
# Compiler flags {{{
LIBS :=
CXXWARNINGS := \
-Wall \
-Wextra \
-Wpointer-arith \
-Wwrite-strings \
-Wmissing-declarations \
-Wno-long-long \
-Wuninitialized \
-Wno-unused-parameter
CXXINCLUDES := \
$(SRCDIR)
COMMONFLAGS := -Wfatal-errors
CXXFLAGS := \
$(shell pkg-config --cflags $(LIBS)) \
-std=c++0x
LDFLAGS := \
$(shell pkg-config --libs $(LIBS))
ifdef RELEASE
COMMONFLAGS := -g0 -O2 $(COMMONFLAGS)
CXXFLAGS := -D_RELEASE $(CXXFLAGS)
else
COMMONFLAGS := -g3 -O0 $(COMMONFLAGS)
endif
CXXFLAGS := $(COMMONFLAGS) $(CXXWARNINGS) $(CXXFLAGS) $(addprefix -I, $(CXXINCLUDES))
# }}}
# Code input and output files {{{
CXXFILES := $(shell find $(SRCDIR) -name *.cc)
DEPFILES := $(CXXFILES:$(SRCDIR)/%.cc=$(DEPDIR)/%.d)
OBJNAMES := $(CXXFILES:$(SRCDIR)/%.cc=%)
OBJFILES := $(OBJNAMES:%=$(OBJDIR)/%.o)
# }}}
-include Makefile.local
# Make targets {{{
.PHONY: all test dep doc clean
# Phony {{{
all: $(BINFILE)
test: $(BINFILE)
./$(BINFILE)
dep: $(DEPFILES)
doc: $(CXXFILES) doxygen.conf
$(Q)doxygen doxygen.conf 1>/dev/null
clean:
$(Q)rm -rf $(OBJDIR) $(BINDIR) $(LIBDIR) $(DEPDIR)
# Include generated dependencies if we're compiling or linking
ifeq (,$(filter $(MAKECMDGOALS),dep doc clean))
-include $(CXXFILES:$(SRCDIR)/%.cc=$(DEPDIR)/%.d)
endif
# }}}
# Output files {{{
$(BINFILE): $(OBJFILES)
$(E)" [$(COLOR_LINK)LD $(COLOR_RESET)] $@"
$(Q)mkdir -p `dirname $@`
$(Q)$(CXX) $(LDFLAGS) -o $@ $(OBJFILES)
$(Q)ln -sf $(PACKAGE_NAME)-$(PACKAGE_VERSION) $(BINDIR)/$(PACKAGE_NAME)
# }}}
# Dependency generation {{{
$(DEPDIR)/%.d: $(SRCDIR)/%.cc
$(E)" [$(COLOR_DEP)DEP$(COLOR_RESET)] $@"
$(Q)mkdir -p `dirname $@`
$(Q)$(CXX) $(CXXFLAGS) -MM -MT $(<:$(SRCDIR)/%.cc=$(OBJDIR)/%.o) -o $@ $<
# }}}
# Code compilation {{{
$(OBJDIR)/%.o: $(SRCDIR)/%.cc
$(E)" [$(COLOR_COMPILE)CXX$(COLOR_RESET)] $<"
$(Q)mkdir -p `dirname $@`
$(Q)$(CXX) -o $@ -c $< $(CXXFLAGS)
# }}}
# }}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment