本文提供一个在GNU/Linux环境下通用的智能Makefile模板,用户可以将其引入到自己的工程当中。即使用户对此
Makefile的工作原理不甚了解,但是只需要修改少数几个关键变量,就可以满足不同的应用需求。
1. 使用环境
GNU make 3.8.1或者以上版本
sed
gcc/binutils
cygwin或者Linux
2. 关键变量
CROSS_COMPILE:交叉编译器前缀
OPTIMIZE:关于优化的编译参数
WARNINGS:关于warning的编译参数
DEFS: 关于宏定义的编译参数
EXTRA_CFLAGS:其它的编译参数
$(OPTIMIZE) $(WARNINGS) $(DEFS) $(EXTRA_CFLAGS)共同构成了传给gcc的编译参数。
INC_DIR:头文件目录
SRC_DIR:源文件目录(当前目录.是被默认包含的)
OBJ_DIR:object文件的输出目录
EXTRA_SRC:源文件列表
EXCLUDE_FILES:exclude文件列表
SUFFIX:源文件的后缀名
TARGET:最终的目标程序名
TARGET_TYPE:目标程序的类型。
可以定义的类型为:ar(static library),so(shared library)和app(application)。
最终Makefile的行为是:
在$(SRC_DIR)定义的每个目录中查找后缀为$(SUFFIX)的文件,并加上$(EXTRA_SRC)中的文件,然后排除掉
$(EXCLUDE_FILES)中的文件,获得本工程定义的源文件列表。对于每一个源文件,编译生成的一个.o文件和一个.d文件
(依赖文件),放在$(OBJ_DIR)目录下。最终生成的目标文件为$(TARGET)。
此Makefile已经充分考虑到文件之间的依赖关系,即,如果某个头文件发生改变,当运行make的时候,所有依赖于它的
源文件都将被重新编译。
###############################################################################
#
# A smart Makefile template for GNU/LINUX programming
#
# Author: PRC (ijkxyz AT msn DOT com)
# Date: 2011/06/17
#
# Usage:
# $ make Compile and link (or archive)
# $ make clean Clean the objectives and target.
###############################################################################
CROSS_COMPILE =
OPTIMIZE := -O2
WARNINGS := -Wall -Wno-unused -Wno-format
DEFS :=
EXTRA_CFLAGS :=
INC_DIR =
SRC_DIR =
OBJ_DIR =
EXTRA_SRC =
EXCLUDE_FILES =
SUFFIX = c cpp cc cxx
TARGET :=
#TARGET_TYPE :=
TARGET_TYPE :=
#TARGET_TYPE :=
#####################################################################################
# Do not change any part of them unless you have understood this script very well #
# This is a kind remind. #
#####################################################################################
#FUNC# Add a new line to the input stream.
define add_newline
$1
endef
#FUNC# set the variable `src-x' according to the input $1
define set_src_x
src-$1 = $(filter-out $4,$(foreach d,$2,$(wildcard $d/*.$1)) $(filter %.$1,$3))
endef
#FUNC# set the variable `obj-x' according to the input $1
define set_obj_x
obj-$1 = $(patsubst %.$1,$3%.o,$(notdir $2))
endef
#VAR# Get the uniform representation of the object directory path name
ifneq ($(OBJ_DIR),)
prefix_objdir = $(shell echo $(OBJ_DIR)|sed 's:\(\./*\)*::')
prefix_objdir := $(filter-out /,$(prefix_objdir)/)
endif
GCC := $(CROSS_COMPILE)gcc
G++ := $(CROSS_COMPILE)g++
SRC_DIR := $(sort . $(SRC_DIR))
inc_dir = $(foreach d,$(sort $(INC_DIR) $(SRC_DIR)),-I$d)
#--# Do smart deduction automatically
$(eval $(foreach i,$(SUFFIX),$(call set_src_x,$i,$(SRC_DIR),$(EXTRA_SRC),$(EXCLUDE_FILES))))
$(eval $(foreach i,$(SUFFIX),$(call set_obj_x,$i,$(src-$i),$(prefix_objdir))))
$(eval $(foreach f,$(EXTRA_SRC),$(call add_newline,vpath $(notdir $f) $(dir $f))))
$(eval $(foreach d,$(SRC_DIR),$(foreach i,$(SUFFIX),$(call add_newline,vpath %.$i $d))))
all_objs = $(foreach i,$(SUFFIX),$(obj-$i))
all_srcs = $(foreach i,$(SUFFIX),$(src-$i))
CFLAGS = $(EXTRA_CFLAGS) $(WARNINGS) $(OPTIMIZE) $(DEFS)
TARGET_TYPE := $(strip $(TARGET_TYPE))
ifeq ($(filter $(TARGET_TYPE),so ar app),)
$(error Unexpected TARGET_TYPE `$(TARGET_TYPE)')
endif
ifeq ($(TARGET_TYPE),so)
CFLAGS += -fpic -shared
LDFLAGS += -shared
endif
PHONY = all .mkdir clean
all: .mkdir $(TARGET)
define cmd_o
$(obj-$1): $2%.o: %.$1 $(MAKEFILE_LIST)
$(GCC) $(inc_dir) -Wp,-MT,$@ -Wp,-MMD,$@.d $(CFLAGS) -c -o $@ $<
endef
$(eval $(foreach i,$(SUFFIX),$(call cmd_o,$i,$(prefix_objdir))))
ifeq ($(TARGET_TYPE),ar)
$(TARGET): AR := $(CROSS_COMPILE)ar
$(TARGET): $(all_objs)
rm -f $@
$(AR) rcvs $@ $(all_objs)
else
$(TARGET): LD = $(if $(strip $(src-cpp) $(src-cc) $(src-cxx)),$(G++),$(GCC))
$(TARGET): $(all_objs)
$(LD) $(LDFLAGS) $(all_objs) -o $@
endif
.mkdir:
@if [ ! -d $(OBJ_DIR) ]; then mkdir -p $(OBJ_DIR); fi
clean:
rm -f $(prefix_objdir)*.o $(TARGET)
-include $(patsubst %.o,%.o.d,$(all_objs))
.PHONY: $(PHONY)
========================================================== 升级版本。与之前版本相比,有如下改动: 1. 在objdir中生成与source相似的目录树,防止不同source目录下同名的源文件生成的obj文件相互覆盖。 2. 在编译过程中,默认显示短命令。可以通过变量设置切换为显示长命令。 3. 用户可自扩展编译规则。 ========================================================== 模板中用到的可配置的变量列表: DEFINES: 定义编译参数,一般用-U或者-D进行宏定义。 EXTRA_CFLAGS: 定义其它的编译参数 inc-y: 头文件搜索目录 src-y: 源文件列表。其中以/结尾的表示目录,其它的表示文件。 SOURCE_SUFFIXES: 源文件后缀名。在src-y指定的目录中搜索以$(SOURCE_SUFFIXES)为后缀的文件,加入到源文件列表中。 例如: src-y = dir1/ dir2/ file9.c SOURCE_SUFFIXES := c cpp 最终形成的源文件列表为: dir1/*.c dir1/*.cpp dir2/*.c dir2/*.cpp file9.c obj-y: 加入连接的obj文件列表。通常这些obj文件不通过源文件编译产生。 ucmd_X: 自定义后缀名为X的源文件的编译规则。 EXCLUDE_FILES: 不参与编译的源文件列表。 OBJECT_DIR:obj文件的输出目录。 LIBS:连接时需要的lib文件。 LDFLAGS:连接参数。 OBJECT_SUFFIX: obj文件的后缀名 DEPEND_SUFFIX: depend文件的后缀名 TARGET: 整个工程最终产生的target文件名。 TARGET_TYPE: $(TARGET)类型。 TARGET_DEPENDS: $(TARGET)的依赖。 CENTRALIZED_SINGLE_DEPEND_FILE: 将所有依赖关系集中生成到同一个depend文件中。默认是每个obj产生一个单独的depend文件。 VERBOSE_COMMAND: 编译过程中显示完整的命令。 |
###############################################################################
#
# A FLEXIBLE MAKEFILE TEMPLATE
#
# The purpose of implementing this script is help quickly deploy source code
# tree during initial phase of development. It is designed to manage one whole
# project from within one single makefile and to be easily adapted to
# different directory hierarchy by simply setting user configurable variables.
# This script is expected to be used with gcc toolchains on bash-compatible
# shell.
#
# Author: Pan Ruochen <coderelease@163.com>
# Date: 2012/10/10
#
###############################################################################
#-----------------------------------------------------------------------------------------------------#
# User configurable variables
#
# ====================================================================================================
# GNU_TOOLCHAIN_PREFIX: The perfix of gnu toolchain.
# ====================================================================================================
# DEFINES: The compiler flags for macro definitions.
# EXTRA_CFLAGS: Any other compiler flags.
# inc-y: Header include paths.
# src-y: Sources. The items ending with a trailing / are regarded as directories, the others
# are regareded as files. The files with specified suffixes in those directories will
# be automatically involved in compilation.
# obj-y: Extra object file list.
# ucmd_X: User defined command to generate targets for the prerequisites
# whith the specified suffix X (i.e, X could be c, cpp, etc).
#
# EXCLUDE_FILES: The files that are not included during compilation.
# OBJECT_DIR: The directory where object files are output.
# LD_SCRIPT: The explicit linker script for linking.
# LIBS: The libraries for linking.
# LDFLAGS: All other linker flags.
# ====================================================================================================
# STRIP_UNUSED: Remove all unreferenced functions and data during linking.
# SOURCE_SUFFIXES:The suffixes of source files.
# OBJECT_SUFFIX: The suffix of object files.
# DEPEND_SUFFIX: The suffix of dependency files.
# TARGET_TYPE: The target type which can be application, shared object, archive library etc.
# TARGET: The path name of the final target.
# IGNORE_ME: The changes of this script will not cause remaking of any target.
# CENTRALIZED_SINGLE_DEPEND_FILE: Use one single dependency file instead of
# generating one dependency file for each source file.
# TARGET_DEPENDS: The dependent targets by the final target.
# VERBOSE_COMMAND:Display verbose commands instead of short commands during the make process.
#-----------------------------------------------------------------------------------------------------#
#****************************************************************************#
# PART II: FUNCTIONALITY IMPLEMENTATIONS #
#****************************************************************************#
# Quiet commands
ifeq ($(VERBOSE_COMMAND),)
Q = @
Q_compile = @echo ' CC $$< => $$@';
Q_link = @echo ' LD $@';
Q_ar = @echo ' AR $@';
Q_mkdir = echo ' MKDIR $1';
Q_clean = @echo ' CLEAN';
Q_distclean = @echo ' DISTCLEAN';
endif
O := $(if $(OBJECT_SUFFIX),$(OBJECT_SUFFIX),o)
D := $(if $(DEPEND_SUFFIX),$(DEPEND_SUFFIX),d)
ifndef SOURCE_SUFFIXES
SOURCE_SUFFIXES := c cpp cc cxx S s
endif
GCC := $(GNU_TOOLCHAIN_PREFIX)gcc
src-d = $(filter %/,$(src-y))
src-f = $(foreach i,$(SOURCE_SUFFIXES),$(filter %.$i,$(src-y)))
is_equal = $(if $(filter $1,$2),$(filter $2,$1))
objdir := $(shell echo $(OBJECT_DIR)|sed -e 's:\(\./*\)*::g')
ifeq ($(objdir),)
objdir := ./
else
objdir := $(objdir)/
have_objdir := y
endif
## Combine compiler flags togather.
CFLAGS = $(foreach i,$(inc-y),-I$i) $(EXTRA_CFLAGS) $(DEFINES)
## Output file types:
## EXE: Application
## AR: static library
## SO: shared object
## DLL: dynamic link library
## BIN: raw binary
TARGET_TYPE := $(strip $(TARGET_TYPE))
ifeq ($(filter $(TARGET_TYPE),SO DLL AR EXE BIN),)
$(error Unknown TARGET_TYPE `$(TARGET_TYPE)')
endif
ifneq ($(filter DLL SO,$(TARGET_TYPE)),)
CFLAGS += -shared
LDFLAGS += -shared
endif
ifneq ($(STRIP_UNUSED),)
CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS += --gc-sections
endif
ifeq ($(CENTRALIZED_SINGLE_DEPEND_FILE),)
CFLAGS += -MMD -MF $$@.$(D) -MT $$@
else
single_depend_file := $(objdir)depend
endif
g_makefile_list = $(if $(IGNORE_ME),,$(MAKEFILE_LIST))
#--------------------------------------------------#
# Exclude user-specified files from source list. #
# $1 -- The sources list #
#--------------------------------------------------#
exclude = $(filter-out $(EXCLUDE_FILES),$1)
#----------------------------------------------------------#
# List files with specified suffix inside the directory. #
# $1 -- The directory #
# $2 -- The suffix #
#----------------------------------------------------------#
ls = $(wildcard $1*.$2)
#---------------------------------------------#
# Replace the specified suffixes with $(O). #
# $1 -- The file names #
# $2 -- The suffixes #
#---------------------------------------------#
get_object_names = $(strip $(foreach i,$2,$(patsubst %.$i,%.$O,$(filter %.$i,$1))))
#---------------------------------------------#
# Get the suffix name from a file name. #
# $1 -- The file name #
# $2 -- The favorite suffixes #
#---------------------------------------------#
get_suffix_names = $(strip $(foreach i,$2,$(if $(filter %.$i,$1),$i)))
#-------------------------------------------------------------------#
# Replace the pattern .. with !! in the path names in order that #
# no directories are out of the object directory #
# $1 -- The path names #
#-------------------------------------------------------------------#
objdir_transform = $(if $(have_objdir),$(subst ..,!!,$1),$1)
#------------------------------------------------------------------#
# Set up static pattern rules for sources with specified suffixes #
# in specified directories. #
# $1 -- Source directories #
# $2 -- Source suffixes #
# $3 -- Equal to $(call ls $1,$2) #
#------------------------------------------------------------------#
static_pattern_rules = $(if $3,$(call __static_pattern_rule,$(patsubst %.$2,$(objdir)%.$O,$3),$1,$2))
#------------------------------------#
# Command to make directory #
# $1 -- The directory to be made #
#------------------------------------#
define cmd_make_directory
$(Q)if test ! -d "$1"; then $(Q_mkdir)mkdir -p "$1"; fi
endef
cmd_compile = $(Q_compile)$(if $(ucmd_$1),$(ucmd_$1),$(GCC) -I$$(dir $$<) $(CFLAGS) -c -o $$@ $$<)
#------------------------------------------------------------------#
# Static pattern rule #
# $1 -- Targets #
# $1 -- Source directories #
# $3 -- The source suffix #
#------------------------------------------------------------------#
define __static_pattern_rule
$(call objdir_transform,$1): $(call objdir_transform,$(objdir)$2%.$(O)): $2%.$3 $(g_makefile_list)
$(call cmd_compile,$3)
endef
#--------------------------------------------------------------#
# Ordinary rule #
# $1 -- The prerequisite #
# $2 -- The Target #
#--------------------------------------------------------------#
define ordinary_rule
$(call objdir_transform,$2): $1 $(g_makefile_list)
$(call cmd_compile,$(call get_suffix_names,$1,$(SOURCE_SUFFIXES)))
endef
#--------------------------------------------------------#
# Make sure the default target "all" is the first target
#--------------------------------------------------------#
PHONY = all clean distclean make_sub_dirs
all: make_sub_dirs $(TARGET)
#----------------------------------------------------#
# Dynamic Targets
#----------------------------------------------------#
$(eval $(foreach i,\
$(sort $(src-d)),\
$(foreach j,$(SOURCE_SUFFIXES),$(call static_pattern_rules,$i,$j,$(call exclude,$(call ls,$i,$j)))))\
$(foreach i,$(call exclude,$(sort $(src-f))),$(call ordinary_rule,$i,$(objdir)$(call get_object_names,$i,$(SOURCE_SUFFIXES)))))
#-------------------------------------#
# Get the list of all source files #
#-------------------------------------#
srcs = $(call exclude,\
$(foreach i,$(SOURCE_SUFFIXES),\
$(foreach j,$(src-d),\
$(wildcard $j*.$i)) $(filter %.$i,$(src-f))))
ifeq ($(strip $(srcs)),)
$(error Empty source list! Please check both src-y and SOURCE_SUFFIXES are correctly set.)
endif
#-------------------------------------#
# Get the list of all object files #
#-------------------------------------#
objs = $(call objdir_transform,$(addprefix $(objdir),$(call get_object_names,$(srcs),$(SOURCE_SUFFIXES))))
objs += $(obj-y)
#----------------------------------------------------#
# Static Targets
#----------------------------------------------------#
make_sub_dirs:
$(call cmd_make_directory,$(dir $(TARGET)))
$(foreach i,$(call objdir_transform,$(sort $(src-d) $(dir $(src-f)))),$(call cmd_make_directory,$(objdir)$i))
ifneq ($(single_depend_file),)
$(single_depend_file): $(srcs) $(filter-out $@,$(g_makefile_list)) $(objdir)
$(GCC) $(CFLAGS) -MM -MG $(srcs) | \
sed 's#\([^[:space:]]\+\)\.$O:\s\([^[:space:]]\+\)\.\([^[:space:].]\+\s\?\)#$(objdir)\2.$O: \2.\3#g' > $@
$(objdir): ; $(call cmd_make_directory,$(objdir))
endif
ifeq ($(TARGET_TYPE),AR)
$(TARGET): AR := $(GNU_TOOLCHAIN_PREFIX)ar
$(TARGET): $(TARGET_DEPENDS) $(objs)
$(Q_ar)rm -f $@ && $(AR) rcvs $@ $(objs)
else
ifeq ($(TARGET_TYPE),BIN)
tmp_target = $(basename $(TARGET)).elf
LDFLAGS += -nodefaultlibs -nostdlibs -nostartupfiles
$(TARGET): $(tmp_target)
$(GNU_TOOLCHAIN_PREFIX)objcopy -O binary $(tmp_target) $@
$(GNU_TOOLCHAIN_PREFIX)objdump -d $(tmp_target) > $(basename $(@F)).lst
$(GNU_TOOLCHAIN_PREFIX)nm $(tmp_target) | sort -k1 > $(basename $(@F)).map
else
tmp_target = $(TARGET)
endif
$(tmp_target): LD = $(if $(foreach i,cpp cc cxx,$(filter %.$i,$(srcs))),$(GNU_TOOLCHAIN_PREFIX)g++,$(GCC))
$(tmp_target): $(TARGET_DEPENDS) $(objs) $(LD_SCRIPT)
$(Q_link)$(LD) $(LDFLAGS) $(if $(LD_SCRIPT),-T $(LD_SCRIPT)) $(objs) $(LIBS) -o $(tmp_target)
endif
clean:
$(Q_clean)rm -rf $(filter-out ./,$(objdir)) $(TARGET) $(filter-out $(obj-y),$(objs))
distclean: clean
$(Q_distclean)find -name '*.$O' -o -name '*.$D' | xargs rm -f; $(if $(single_depend_file),rm -f $(single_depend_file))
print-%:
@echo $* = $($*)
.DEFAULT_GOAL = all
sinclude $(if $(filter all,$(if $(MAKECMDGOALS),$(MAKECMDGOALS),$(.DEFAULT_GOAL))), \
$(if $(single_depend_file),$(single_depend_file),$(foreach i,$(objs),$i.$(D))))
example
linux@ubuntu:~/Workspace/app$ tree -a
.
|-- GNUmakefile
|-- include
| `-- common.h
|-- main.c
|-- src1
| |-- a1-1.h
| |-- a1-2.h
| |-- a1.c
| |-- a2-2.h
| |-- a2.cpp
| `-- skipme1.c
|-- src2
| |-- a
| | |-- a2a-1.cc
| | |-- a2a-2.cxx
| | `-- skipme2.c
| `-- b
| `-- a2b.c
|-- src3
| |-- a3.c
| `-- z3.c
`-- src4
|-- a4.c
`-- z4.cpp
7 directories, 17 files
###############################################################################
#
# A smart Makefile template for GNU/LINUX programming
#
# Author: PRC (ijkxyz AT msn DOT com)
# Date: 2011/06/17
#
# Usage:
# $ make Compile and link (or archive)
# $ make clean Clean the objectives and target.
###############################################################################
CROSS_COMPILE =
OPTIMIZE := -O2
WARNINGS := -Wall -Wno-unused -Wno-format
DEFS := -DMYDEF=1 -UMYDEF2
EXTRA_CFLAGS :=
INC_DIR = include
SRC_DIR = src1 src2/a src2/b
OBJ_DIR = out/target
EXTRA_SRC = src3/z3.c src4/z4.cpp
EXCLUDE_FILES = src1/skipme1.c src2/a/skipme2.c
SUFFIX = c cpp cc cxx
TARGET := out/go.exe
#TARGET_TYPE := ar
TARGET_TYPE := app
#TARGET_TYPE := so
#####################################################################################
# Do not change any part of them unless you have understood this script very well #
# This is a kind remind. #
#####################################################################################
#FUNC# Add a new line to the input stream.
define add_newline
$1
endef
#FUNC# set the variable `src-x' according to the input $1
define set_src_x
src-$1 = $(filter-out $4,$(foreach d,$2,$(wildcard $d/*.$1)) $(filter %.$1,$3))
endef
#FUNC# set the variable `obj-x' according to the input $1
define set_obj_x
obj-$1 = $(patsubst %.$1,$3%.o,$(notdir $2))
endef
#VAR# Get the uniform representation of the object directory path name
ifneq ($(OBJ_DIR),)
prefix_objdir = $(shell echo $(OBJ_DIR)|sed 's:\(\./*\)*::')
prefix_objdir := $(filter-out /,$(prefix_objdir)/)
endif
GCC := $(CROSS_COMPILE)gcc
G++ := $(CROSS_COMPILE)g++
SRC_DIR := $(sort . $(SRC_DIR))
inc_dir = $(foreach d,$(sort $(INC_DIR) $(SRC_DIR)),-I$d)
#--# Do smart deduction automatically
$(eval $(foreach i,$(SUFFIX),$(call set_src_x,$i,$(SRC_DIR),$(EXTRA_SRC),$(EXCLUDE_FILES))))
$(eval $(foreach i,$(SUFFIX),$(call set_obj_x,$i,$(src-$i),$(prefix_objdir))))
$(eval $(foreach f,$(EXTRA_SRC),$(call add_newline,vpath $(notdir $f) $(dir $f))))
$(eval $(foreach d,$(SRC_DIR),$(foreach i,$(SUFFIX),$(call add_newline,vpath %.$i $d))))
all_objs = $(foreach i,$(SUFFIX),$(obj-$i))
all_srcs = $(foreach i,$(SUFFIX),$(src-$i))
CFLAGS = $(EXTRA_CFLAGS) $(WARNINGS) $(OPTIMIZE) $(DEFS)
TARGET_TYPE := $(strip $(TARGET_TYPE))
ifeq ($(filter $(TARGET_TYPE),so ar app),)
$(error Unexpected TARGET_TYPE `$(TARGET_TYPE)')
endif
ifeq ($(TARGET_TYPE),so)
CFLAGS += -fpic -shared
LDFLAGS += -shared
endif
PHONY = all .mkdir clean
all: .mkdir $(TARGET)
define cmd_o
$$(obj-$1): $2%.o: %.$1 $(MAKEFILE_LIST)
$(GCC) $(inc_dir) -Wp,-MT,$$@ -Wp,-MMD,$$@.d $(CFLAGS) -c -o $$@ $$<
endef
$(eval $(foreach i,$(SUFFIX),$(call cmd_o,$i,$(prefix_objdir))))
ifeq ($(TARGET_TYPE),ar)
$(TARGET): AR := $(CROSS_COMPILE)ar
$(TARGET): $(all_objs)
rm -f $@
$(AR) rcvs $@ $(all_objs)
else
$(TARGET): LD = $(if $(strip $(src-cpp) $(src-cc) $(src-cxx)),$(G++),$(GCC))
$(TARGET): $(all_objs)
$(LD) $(LDFLAGS) $(all_objs) -o $@
endif
.mkdir:
@if [ ! -d $(OBJ_DIR) ]; then mkdir -p $(OBJ_DIR); fi
clean:
rm -f $(prefix_objdir)*.o $(TARGET)
-include $(patsubst %.o,%.o.d,$(all_objs))
.PHONY: $(PHONY)
原文地址:http://bbs.chinaunix.net/thread-3553668-1-1.html
网上盛传的另一个makefile,我稍微修改了一下:
#############################################################################
#
# Generic Makefile for C/C++ Program
#
# License: GPL (General Public License)
# Author: whyglinux <whyglinux AT gmail DOT com>
# 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 <SRCDIRS>
# * 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
#
#===========================================================================
## Customizable Section: adapt those variables to suit your program.
##==========================================================================
-include ../Rules.make
# The pre-processor and compiler options.
MY_CFLAGS =
# The linker options.
MY_LIBS =
# The pre-processor options used by the cpp (man cpp for more).
CPPFLAGS = -Wall
# The options used in linking as well as in any direct use of ld.
LDFLAGS += -lrt
# The directories in which source files reside.
# If not specified, only the current directory will be serached.
SRCDIRS = ./kf_base ./kf_net ./kf_share .
# The executable file name.
# If not specified, current directory name or `a.out' will be used.
PROGRAM = kfserver
## Implicit Section: change the following only when necessary.
##==========================================================================
# The source file types (headers excluded).
# .c indicates C source files, and others C++ ones.
#SRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp
SRCEXTS = .c
# The header file types.
#HDREXTS = .h .H .hh .hpp .HPP .h++ .hxx .hp
HDREXTS = .h
# The pre-processor and compiler options.
# Users can override those variables from the command line.
CFLAGS = -g -O0 -Wall -mcpu=arm926ej-s
CXXFLAGS= -g -O2
GNU_TOOLCHAIN_PREFIX = $(CSTOOL_PREFIX)
# The C program compiler.
CC := $(GNU_TOOLCHAIN_PREFIX)gcc
# The C++ program compiler.
#CXX = g++
# Un-comment the following line to compile C programs as C++ ones.
#CC = $(CXX)
# The command used to delete file.
#RM = rm -f
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
#VERBOSE_COMMAND = quiet
## Quiet commands
ifeq ($(VERBOSE_COMMAND),)
Q = @
Q_compile = @echo ' CC $< => $@';
Q_link = @echo ' LD $@';
Q_ar = @echo ' AR $@';
Q_mkdir = echo ' MKDIR $1';
Q_clean = @echo ' CLEAN';
Q_distclean = @echo ' DISTCLEAN';
endif
## Stable Section: usually no need to be changed. But you can add more.
##==========================================================================
SHELL = /bin/sh
EMPTY =
SPACE = $(EMPTY) $(EMPTY)
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 ($(SRCDIRS),)
SRCDIRS = .
endif
SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
HEADERS = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(HDREXTS))))
CFLAGS = $(foreach i,$(SRCDIRS),-I$i)
SRC_CXX = $(filter-out %.c,$(SOURCES))
OBJS = $(addsuffix .o, $(basename $(SOURCES)))
DEPS = $(OBJS:.o=.d)
## Define some useful variables.
DEP_OPT = $(shell if `$(CC) --version | grep "GCC" >/dev/null`; then \
echo "-MM -MP"; else echo "-M"; fi )
DEPEND = $(CC) $(DEP_OPT) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS)
DEPEND.d = $(subst -g ,,$(DEPEND))
COMPILE.c = $(Q_compile)$(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) -c
COMPILE.cxx = $(Q_compile)$(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c
LINK.c = $(Q_link)$(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LINK.cxx = $(Q_link)$(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
.PHONY: all objs tags ctags clean distclean help show
# Delete the default suffixes
.SUFFIXES:
all: $(PROGRAM)
# Rules for creating dependency files (.d).
#------------------------------------------
%.d:%.c
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
%.d:%.C
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
%.d:%.cc
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
%.d:%.cpp
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
%.d:%.CPP
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
%.d:%.c++
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
%.d:%.cp
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
%.d:%.cxx
@echo -n $(dir $<) > $@
@$(DEPEND.d) $< >> $@
# Rules for generating object files (.o).
#----------------------------------------
objs:$(OBJS)
%.o:%.c
$(COMPILE.c) $< -o $@
%.o:%.C
$(COMPILE.cxx) $< -o $@
%.o:%.cc
$(COMPILE.cxx) $< -o $@
%.o:%.cpp
$(COMPILE.cxx) $< -o $@
%.o:%.CPP
$(COMPILE.cxx) $< -o $@
%.o:%.c++
$(COMPILE.cxx) $< -o $@
%.o:%.cp
$(COMPILE.cxx) $< -o $@
%.o:%.cxx
$(COMPILE.cxx) $< -o $@
# 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
$(LINK.c) $(OBJS) $(MY_LIBS) -o $@
@echo Type ./$@ to execute the program.
else # C++ program
$(LINK.cxx) $(OBJS) $(MY_LIBS) -o $@
@echo Type ./$@ to execute the program.
endif
ifndef NODEP
ifneq ($(DEPS),)
sinclude $(DEPS)
endif
endif
install:
cp -f kf920.elf /home/linux-138/kf920/rootfs/kfserver
clean:
$(Q_clean)$(RM) $(OBJS) $(PROGRAM) $(PROGRAM).exe
distclean: clean
$(Q_distclean)$(RM) $(DEPS) TAGS
# Show help.
help:
@echo 'Generic Makefile for C/C++ Programs (gcmakefile) version 0.5'
@echo 'Copyright (C) 2007, 2008 whyglinux <whyglinux@hotmail.com>'
@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 AT gmail DOT com>.'
# Show variables (for debug use only.)
show:
@echo 'PROGRAM :' $(PROGRAM)
@echo 'SRCDIRS :' $(SRCDIRS)
@echo 'HEADERS :' $(HEADERS)
@echo 'SOURCES :' $(SOURCES)
@echo 'SRC_CXX :' $(SRC_CXX)
@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 ##
#############################################################################