#############################################################################
#
# Generic Makefile for C/C++ Program
#
# License: GPL (General Public License)
# Author: whyglinux <whyglinux>
# wangmengmeng <wang0_0meng@126.com> 2010/10/16 modified
# Date: 2006/03/04 (version 0.1)
# 2007/03/24 (version 0.2)
# 2007/04/09 (version 0.3)
# 2007/06/26 (version 0.4)
# 2008/04/05 (version 0.5)
#
# Description:
# ------------
# This is an easily customizable makefile template. The purpose is to
# provide an instant building environment for C/C++ programs.
#
# It searches all the C/C++ source files in the specified directories,
# makes dependencies, compiles and links to form an executable.
#
# Besides its default ability to build C/C++ programs which use only
# standard C/C++ libraries, you can customize the Makefile to build
# those using other libraries. Once done, without any changes you can
# then build programs using the same or less libraries, even if source
# files are renamed, added or removed. Therefore, it is particularly
# convenient to use it to build codes for experimental or study use.
#
# GNU make is expected to use the Makefile. Other versions of makes
# may or may not work.
#
# Usage:
# ------
# 1. Copy the Makefile to your program directory.
# 2. Customize in the "Customizable Section" only if necessary:
# * to use non-standard C/C++ libraries, set pre-processor or compiler
# options to <my_cflags> and linker ones to <my_libs>
# (See Makefile.gtk+-2.0 for an example)
# * to search sources in more directories, set to <src_dirs>
# * to specify your favorite program name, set to <program>
# 3. Type make to start building your program.
#
# Make Target:
# ------------
# The Makefile provides the following targets to make:
# $ make compile and link
# $ make NODEP=yes compile and link without generating dependencies
# $ make objs compile only (no linking)
# $ make tags create tags for Emacs editor
# $ make ctags create ctags for VI editor
# $ make clean clean objects and the executable file
# $ make distclean clean objects, the executable and dependencies
# $ make help get the usage of the makefile
# $ make deps compile only dependencies
# $ make showcommands display the commands when compiling
# Must modified section
#===========================================================================
# @SRC_DIRS:The directories in which source files reside. Default is '.'.
# @INC_DIRS:The directories in which header files reside. Default is EMPTY
# @OUT_DIR :The directory in which output files reside. Default is "out"
# @PROGRAM :The output name of the source files. Default is "test"
SRC_DIRS := src
INC_DIRS := include src
OUT_DIR := out
PROGRAM =
# Customizable section
#===========================================================================
# @MY_CFLAGS:The pre-processor and compiler options.
# @MY_LIBS :The linker options.
# @LDFLAGS :The options used in linking as well as in any direct use of ld.
MY_CFLAGS =
MY_LIBS =
LDFLAGS =
CROSS_COMPILE ?=
## Implicit Section: change the following only when necessary.
##==========================================================================
# @CEXTS :The c extentions
# @CPPEXTS :The cpp extentions
CEXTS := .c .C
CPPEXTS := .cc .cpp .CPP .c++ .cxx .cp
HDREXTS = .h .H .hh .hpp .HPP .h++ .hxx .hp
## Auto generated Section: change when you are sure
##==========================================================================
# @SPACE :Represent a space
# @SRCEXTS :All the source this makefile will processed
# @CPARTERNS :Used to generate like %.c %.C
# @CPPPARTERNS:Used to generate like %.cpp %.CPP
# @INCARGS :Used to generate like -Iinclude
EMPTY =
SPACE = $(EMPTY) $(EMPTY)
SRCEXTS := $(CEXTS)$(SPACE)$(CPPEXTS)
CPARTERNS := $(foreach i,$(CEXTS),%$(i))
CPPPARTERNS := $(foreach i,$(CPPEXTS),%$(i))
ifneq ($(INC_DIRS),)
INCARGS = $(foreach i,$(INC_DIRS),-I$(i))
else
INCARGS =
endif
ifneq ($(filter showcommands,$(MAKECMDGOALS)),)
HIDE :=
else
HIDE := @
endif
CFLAGS = -g -O2 -Wall $(INCARGS)
CXXFLAGS = -g -O2 -Wall $(INCARGS)
CC = $(addprefix $(CROSS_COMPILE),gcc)
CXX = $(addprefix $(CROSS_COMPILE),g++)
# Un-comment the following line to compile C programs as C++ ones.
#CC = $(CXX)
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
## Stable Section: usually no need to be changed. But you can add more.
##==========================================================================
SHELL = /bin/sh
ifeq ($(PROGRAM),)
CUR_PATH_NAMES = $(subst /,$(SPACE),$(subst $(SPACE),_,$(CURDIR)))
PROGRAM = $(word $(words $(CUR_PATH_NAMES)),$(CUR_PATH_NAMES))
ifeq ($(PROGRAM),)
PROGRAM = a.out
endif
endif
ifeq ($(SRC_DIRS),)
SRC_DIRS = .
endif
ifeq ($(OUT_DIR),)
OUT_DIR = out
endif
SOURCES = $(foreach d,$(SRC_DIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
HEADERS = $(foreach d,$(SRC_DIRS),$(wildcard $(addprefix $(d)/*,$(HDREXTS))))
SRC_C = $(filter $(CPARTERNS),$(SOURCES))
SRC_CXX = $(filter $(CPPPARTERNS),$(SOURCES))
OBJS = $(addsuffix .o,$(addprefix $(OUT_DIR)/,$(basename $(notdir $(SOURCES)))))
DEPS = $(OBJS:.o=.d)
## Define some useful variables.
DEP_OPT = $(shell if `$(CC) --version | grep "GCC" >/dev/null`; then \
echo "-MM"; else echo "-M"; fi )
DEPEND = $(CC) $(DEP_OPT) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS)
DEPEND.d = $(subst -g ,,$(DEPEND))
COMPILE.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) -c
COMPILE.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c
LINK.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LINK.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
RM = rm -f
# Function to add dependencies
define deps-template
$(1): $(2) $$(OUT_DIR)
@echo "generating dependecy ==> $(1)"
$$(HIDE)$$(DEPEND.d) $(2) $$(INCARGS) | sed '1s#^#$(dir $(1))#' > $(1)
endef
define objs-template
$(1): $(2)
@echo "compiling $(2) ==> $(1)"
$$(HIDE)$(3) $$< -o $$@
endef
## Rules Section: ADD some rules to generate target.
##==========================================================================
.PHONY: all objs tags ctags clean distclean help show showcommands deps
# Delete the default suffixes
.SUFFIXES:
all: $(PROGRAM)
showcommands: all
deps: $(DEPS)
# Rules to create dependency files
$(foreach d,$(SOURCES),$(eval $(call deps-template,$(addsuffix .d,$(OUT_DIR)/$(basename $(notdir $(d)))),$(d))))
# Rules for generating object files (.o).
#----------------------------------------
objs: $(OBJS) $(OUT_DIR)
$(foreach d,$(SRC_CXX),$(eval $(call objs-template,$(addsuffix .o,$(OUT_DIR)/$(basename $(notdir $(d)))),$(d),$(COMPILE.cxx))))
$(foreach d,$(SRC_C),$(eval $(call objs-template,$(addsuffix .o,$(OUT_DIR)/$(basename $(notdir $(d)))),$(d),$(COMPILE.c))))
# Rules for generating the tags.
#-------------------------------------
tags: $(HEADERS) $(SOURCES)
$(ETAGS) $(ETAGSFLAGS) $(HEADERS) $(SOURCES)
ctags: $(HEADERS) $(SOURCES)
$(CTAGS) $(CTAGSFLAGS) $(HEADERS) $(SOURCES)
# Rules for generating the executable.
#-------------------------------------
$(PROGRAM):$(OBJS)
ifeq ($(SRC_CXX),) # C program
@echo linking $@
$(HIDE)$(LINK.c) $(OBJS) $(MY_LIBS) -o $@
@echo Type ./$@ to execute the program.
else
@echo linking $@ # C++ program
$(HIDE)$(LINK.cxx) $(OBJS) $(MY_LIBS) -o $@
@echo Type ./$@ to execute the program.
endif
ifndef NODEP
ifneq ($(DEPS),)
sinclude $(DEPS)
endif
endif
$(OUT_DIR):
$(HIDE)mkdir $(OUT_DIR)
clean:
$(HIDE)$(RM) $(OBJS) $(PROGRAM)
@echo "objs and program cleaned"
distclean: clean
$(HIDE)$(RM) $(DEPS) TAGS
@echo "deps and tags cleaned"
# Show help.
help:
@echo 'Generic Makefile for C/C++ Programs (gcmakefile) version 0.5'
@echo 'Copyright (C) 2007, 2008 whyglinux <whyglinux@hotmail.com>'
@echo 'wangmengmeng <wang0_0meng@126.com> 2010/10/16 modified
@echo
@echo 'Usage: make [TARGET]'
@echo 'TARGETS:'
@echo ' all (=make) compile and link.'
@echo ' NODEP=yes make without generating dependencies.'
@echo ' objs compile only (no linking).'
@echo ' tags create tags for Emacs editor.'
@echo ' ctags create ctags for VI editor.'
@echo ' clean clean objects and the executable file.'
@echo ' distclean clean objects, the executable and dependencies.'
@echo ' show show variables (for debug use only).'
@echo ' help print this message.'
@echo
@echo 'Report bugs to <whyglinux>.'
# Show variables (for debug use only.)
show:
@echo 'PROGRAM :' $(PROGRAM)
@echo 'SRC_DIRS :' $(SRC_DIRS)
@echo 'INC_DIRS :' $(INC_DIRS)
@echo 'OUT_DIR :' $(OUT_DIR)
@echo 'DEPEND.d :' $(DEPEND.d)
@echo 'HEADERS :' $(HEADERS)
@echo 'SOURCES :' $(SOURCES)
@echo 'SRC_CXX :' $(SRC_CXX)
@echo 'SRC_C :' $(SRC_C)
@echo 'OBJS :' $(OBJS)
@echo 'DEPS :' $(DEPS)
@echo 'DEPEND :' $(DEPEND)
@echo 'COMPILE.c :' $(COMPILE.c)
@echo 'COMPILE.cxx :' $(COMPILE.cxx)
@echo 'link.c :' $(LINK.c)
@echo 'link.cxx :' $(LINK.cxx)
## End of the Makefile ## Suggestions are welcome ## All rights reserved ##
#############################################################################
source: http://hi.baidu.com/snownight/blog/item/9ca6b6fd575dec1909244da3.html