http://blog.sina.com.cn/s/blog_6fd68d5f01014bdr.html
基于GNU make的开源大型项目多核并行编译框
1 大型项目编译
大型项目的Makefile编写和维护,是一个令人头疼的问题,本文介绍了一种基于Gnu make 脚本的框架,该框架满足以下功能:
1) 代码精简
支持大型项目编译过程中,确保Makefile文件精简(脚本只有600行左右),方便维护;
2)源代码与编译目标码目录独立
源代码与编译目标码分别位于不同的目录下面,方便进行代码版本管理(如svn管理)。
3)编译脚本扩展复用(同一个makefile支持多个项目编译),方便部署和维护;
通过将make调用makefile命令封装为脚本命令,可以使用单一脚本来实现多个项目复用同一个makefile文件;
4)支持linux下系统多核并行编译(包括32位和64位)
注:该工具已经在很多大型开源项目中编译使用,感兴趣的朋友可以与本人留言联系,或者加QQ交流。
2 框架说明
2.1 代码相关说明
整个框架包含两个主文件:
1)主makefile 文件
2)nb(no-make-building)脚本文件(封装了make调用makefile文件的shell脚本)
2.2 框架支持的项目结构:
linux系统下:
../prjname/src: 代码目录,prjname为项目名称
../prjname/output:项目编译输出目录。
2.3 makefile脚本文件代码
注:博客不能支持插入代码和测试项目工程的压缩包,只能贴出脚本的代码了(600行左右),测试工程可以自己写hello 项目进行编译测试。
脚本内容如下:
#假定编译工具脚本部署在/home/nb目录下:
NBDIR:=/home/nb
PRJLIST:=test2 test
ARCHS:=i686 mips
defaultARCH:=i686
.PHONY:default all $(ARCH) help
default:
CLEANS:=clean cl686 clmips
other_goals:= help $(CLEANS)
#project name set:
#Get current prject name:
PRJNAME:=$(filter $(PRJLIST), $(subst /, ,$(abspath .)))
TOPDIR:=$(firstword $(subst /$(PRJNAME)/src, ,$(abspath ./)))
#project's source path must be the style of: xxx/$(PRJNAME)/src
SRCDIR:=$(TOPDIR)/$(PRJNAME)/src
OUTPUTDIR:=$(TOPDIR)/$(PRJNAME)/output
ifeq ("$(PRJNAME)", "")
ifneq ("$(MAKECMDGOALS)","help")
$(error you must running make in project($(PRJLIST))'s source directory!)
endif
endif
#default goal is i686:
ifeq ("$(MAKECMDGOALS)","")
ARCH:=$(defaultARCH)
MAKECMDGOALS:=$(defaultARCH)
else
ifeq ("$(MAKECMDGOALS)","i686")
ARCH:=i686
else
ifeq ("$(MAKECMDGOALS)","mips")
ARCH:=mips
else
ifneq ("$(filter $(MAKECMDGOALS),$(main_goals) $(shell ls $(SRCDIR)))","")
#the goal is a subpath ,so compiling it i686 obj code.
ARCH:=i686
else
#make rules.mk file :
ifeq ("$(MAKECMDGOALS)","create_rule_file")
ARCH:=$(THEARCH)
endif
endif
endif
endif
endif
#clean goal:i686_clean, mips_clean:
ifeq ("$(MAKECMDGOALS)","clmips")
ARCH:=mips
else
ifeq ("$(MAKECMDGOALS)","cl686")
ARCH:=i686
endif
endif
#version info:
APP_RELEASE:=3.0.0
#support source type list:
C_PLUS_PLUS_TYPES:=%.cc %.cpp %.cxx
C_TYPES:=%.c
ARCHDIR:=$(OUTPUTDIR)/$(ARCH)
LIBDIR:=$(ARCHDIR)/lib
BINDIR:=$(ARCHDIR)/bin
SRCOBJDIR:=$(ARCHDIR)/$(PRJNAME)/src
#****************************PROJECT CONFIG BEGIN**************************************
#****************************test project setup end
#test project setup begin:*******************************************
test_i686_g++ :=g++
test_i686_gcc :=gcc
test_mips_g++:=g++
test_mips_gcc:=gcc
#C++ compiling flags:
test_i686_CXXFLAGS :=-g -O2 -Wall -Werror -fPIC
test_mips_CXXFLAGS:=-g -O2 -Wall -Werror -fPIC
#C compiling flags:
test_i686_CCFLAGS:=-g -O2 -Wall -Werror -fPIC
test_mips_CCFLAGS:=-g -O2 -Wall -Werror -fPIC
#project linking FLAGS:
test_LINKFLAGS:=-shared -L$(LIBDIR)
#compiling include header file finding path:
test_IPATH:=-pthread -I.
#for lib linking processing lib file finding path:
test_LLPATH:=
#for program linking processing lib file finding path:
test_PLPATH:=
#*********************************PROJECT CONFIG END**********************************
#test2 project setup begin:*******************************************
test2_DEP_PROJECT:=test
test2_i686_g++ :=g++
test2_i686_gcc :=gcc
test2_mips_g++:=g++
test2_mips_gcc:=gcc
#C++ compiling flags:
test2_i686_CXXFLAGS :=-g -O2 -Wall -Werror -fPIC
test2_mips_CXXFLAGS:=-g -O2 -Wall -Werror -fPIC
#C compiling flags:
test2_i686_CCFLAGS:=-g -O2 -Wall -Werror -fPIC
test2_mips_CCFLAGS:=-g -O2 -Wall -Werror -fPIC
#project linking FLAGS:
test2_LINKFLAGS:=-shared -L$(LIBDIR)
#compiling include header file finding path:
test2_IPATH:=-pthread -I.
#for lib linking processing lib file finding path:
test2_LLPATH:=
#for program linking processing lib file finding path:
test2_PLPATH:=
#C++ compiler:
g++:=$($(PRJNAME)_$(ARCH)_g++)
#C compiler:
gcc:=$($(PRJNAME)_$(ARCH)_gcc)
#C compiling FLAGS:
CCFLAGS:=$($(PRJNAME)_$(ARCH)_CCFLAGS)
#C++ compiling FLAGS:
CXXFLAGS:=$($(PRJNAME)_$(ARCH)_CXXFLAGS)
#LINKFLAGS:
LINKFLAGS:=$($(PRJNAME)_LINKFLAGS)
#--$1: lib name,
#--$2: lib src file list name,accord *.c or *.cc get *.lo file list!
#--$3: dependent lib name.
#--$4: Object file path.
#--$5: src file path.
#--$6: rules.mk file full name
define create_lib_rule
#get *.lo file list from src file(*.cc,*.c, *.cpp ,and so on)
depobjs:=$(addprefix $4,$(addsuffix .lo,$(basename $(filter $(C_PLUS_PLUS_TYPES) $(C_TYPES),$(notdir $2)))))
#adding dependent lib file,muse to filter these lib not generated by CMN/MME compiling.
deplibs:=$$(filter $(allgenlibs),$3)
deplibs_fullname:=$$(addprefix $(LIBDIR)/lib,$$(addsuffix .so,$$(deplibs)))
depfiles:=$$(depobjs) $$(deplibs_fullname)
#attention:goal full name not including version info:
goal:=$(LIBDIR)/lib$1.so
cmdline:=$(g++) $(LINKFLAGS)
#adding linking need lib name:
cmdline+=$$(if $3,$$(addprefix -l,$3),)
#attention:linking output goal including version:
lib_version:=$($1_VERSION)
cmdline+=-o $$(goal)$$(if $$(lib_version),.$$(lib_version),) $$(depobjs) $(LLPATH)
#save rule to file:
$$(shell echo "#linking $(LIBDIR)/lib$1.so$$(if $$(lib_version),.$$(lib_version),) library rule:" >> $6)
$$(shell echo "$$(goal):$$(depfiles)" >> $6)
$$(shell echo " @echo Linking library lib$1.so$$(if $$(lib_version),.$$(lib_version),) from ...$$(subst $(TOPDIR),,$4) && echo cd $5 && echo $$(cmdline) " >> $6)
$$(shell echo " @ cd $5 && $$(cmdline) " >> $6)
ifneq ("$$(lib_version)","")
$$(shell echo " @echo cd $(LIBDIR) && echo ln -sf lib$1.so.$$(lib_version) lib$1.so " >> $6)
$$(shell echo " @cd $(LIBDIR) && ln -sf lib$1.so.$$(lib_version) lib$1.so && echo" >> $6)
else
$$(shell echo " @echo " >> $6)
endif
$$(shell echo " " >> $6)
#create source file compiling rules:
$(foreach src,$(strip $($1_SRCS)),$(eval $(call create_obj_rule,$5,$4,$(src),$1,$6)))
endef
#--$1: src file path
#--$2: obj file path
#--$3: src file name
#--$4: program name or lib name (according it to get source compiling flags)
#--$5: rules.mk file full name
define create_obj_rule
#rule goal and dependent setup:
goal:=$$(addprefix $(strip $2),$(strip $(subst $(suffix $3),.lo,$(notdir $3))))
depfiles:=$(if $(wildcard $1$3),$1$3,$(if $(wildcard $3),$3,$1$3))
#not create the same rules:
ifeq ("$$(filter $$(goal),$(make.mk.objs))","")
make.mk.objs+=$$(goal)
#select compiler and compiling flags, according src file suffix(.cc,*.cpp/.c)
cmdline:=$(if $(filter $(C_PLUS_PLUS_TYPES),$(suffix $(firstword $3))),$(g++) $(CXXFLAGS),$(gcc) $(CCFLAGS))
#adding in make.mk define flags:(for C++)
#CXXFLAGS relative path processing:such as -I../../path->-I$(CURDIR)/../../path
cmdline+=-I$1
#compiling FLAGS:
tempFlags+=$($4_CXXFLAGS) $($4_CCFLAGS)
cmdline+=$$(tempFlags)
#adding current src path for header file search :
cmdline+=$(IPATH)
#adding compiling obj file and src file:
cmdline+=-o $$(goal) -c $$(depfiles)
$$(shell echo "#source file compiling to *.lo file rule:" >> $5)
$$(shell echo "$$(goal):$$(depfiles)" >> $5)
$$(shell echo " @echo Compiling source file $$(notdir $$(depfiles)) in ...$$(subst $(TOPDIR),,$$(dir $$(depfiles)))" >> $5)
$$(shell echo " @cd $1 && $$(cmdline) " >> $5)
$$(shell echo " @echo cd $1 && echo $$(cmdline) && echo " >> $5)
$$(shell echo " allobjs+=$$(goal)" >> $5)
$$(shell echo " " >> $5)
endif
endef
#--$1: program name,
#--$2: program src file list name,accord *.c or *.cc get *.lo file list!
#--$3: program dependent lib name.
#--$4: Object file path.
#--$5: src file path.
#--$6: rules.mk file full name
define create_program_rule
#get dependent file list: *.Io(converting from *.cpp, *.cc,*.c,and so on.)
depobjs:=$(addprefix $4,$(addsuffix .lo,$(basename $(filter %.c %.cc %.cpp,$(notdir $2)))))
#adding dependent lib file,muse to filter these lib not generated by CMN/MME compiling.
#hard code for make.mk vars not standard!!!!!
#two type of program dep. libs naming: xxx_LIBS, $(ARCH)_xxx_LIBS.
deplibs:=$$(filter $(allgenlibs),$$(if $3,$3,$$($(ARCH)_$1_LIBS)))
deplibs_fullname:=$$(addprefix $(LIBDIR)/lib,$$(addsuffix .so,$$(deplibs)))
depfiles:=$$(depobjs) $$(deplibs_fullname)
goal:=$(BINDIR)/$1
#program link no need $(LINKFLAGS) ,it is not the same as lib link flags!
cmdline:=$(g++) $(PLPATH)
#adding goal, dep obj fils(*.lo)
cmdline+=-o $$(goal) $$(depobjs)
#adding linking dep. lib name:
llibs:=$$(if $3,$3,$$($(ARCH)_$1_LIBS))
cmdline+=$$(addprefix -l,$$(llibs))
#adding linking flags:
cmdline+=$(PLFLAGS)
#save rule to file:
$$(shell echo "Program linking rule:" >> $6)
$$(shell echo "$$(goal):$$(depfiles)" >> $6)
$$(shell echo " @echo Linking program $1 from ...$$(subst $(TOPDIR),,$4)" >> $6)
$$(shell echo " @echo cd $5 && echo $$(cmdline) " >> $6)
$$(shell echo " @cd $5 && $$(cmdline) && echo " >> $6)
$$(shell echo " " >> $6)
#create source file compiling rules:
$(foreach src,$(strip $($1_SRCS)),$(eval $(call create_obj_rule,$5,$4,$(src),$1,$6)))
endef
#-$1--make.mk file full name
define precreate_rules
PROGRAMS:=
LIBRARIES:=
SUBDIRS:=
include $1
#Create Filter make.mk list:
compilingdirs:=$$(if $$(SUBDIRS),$$(SUBDIRS),$$(allcards_SUBDIRS))
cur_subdirs:=$$(filter-out %svn,$(notdir $(shell find $(dir $1) -maxdepth 1 -type d)))
filter_dirs:=$$(filter-out $$(compilingdirs),$$(cur_subdirs))
Filter_make.mk:=$$(if $$(filter_dirs),$$(addprefix $(dir $1),$$(addsuffix /%,$$(filter_dirs))),)
#repeative value not adding:
Filter_make.mks+=$$(if $$(filter $$(Filter_make.mks),$$(Filter_make.mk)),,$$(Filter_make.mk))
ifeq ("$$(filter $$(Filter_make.mks),$1)","")
libs:=$$(LIBRARIES)
#lib simple name:
allgenlibs+=$$(libs)
#lib full names:
alllibs+=$$(addprefix $(LIBDIR)/lib,$$(addsuffix .so,$$(libs)))
programs:=$$(PROGRAMS)
#program fullname:
allprograms+=$$(addprefix $(BINDIR)/,$$(programs))
#allobjs not sum here:because the same source file can be compiling to defferent path, so sum in create_obj_rule file.
endif
endef
#-$1--make.mk file full name
#-$2--rules_setup.mk file full name
#-$3--rules.mk file full name
#--this function create temp rules_setup.mk file so as to create real rulse ,include *.cc/*.c compiling ,*.so linking ,program linking rules,and so on.
define create_rule_files
#create rule template file:
srcdir:=$(dir $1)
#curdir:this var used by make.mk file calling $(wildcard ...) function:
curdir:=$(dir $1)
objdir:=$(SRCOBJDIR)$(subst $(SRCDIR),,$(dir $1))
rules_setup.mk:=$2
#now create rules_setup.mk file:
$$(shell mkdir -p $$(objdir))
rules.mk:=$3
$$(shell echo "#all rules:" > $$(rules.mk))
PROGRAMS:=
LIBRARIES:=
include $1
libs:=$$(LIBRARIES)
$$(shell echo " include $1" >$$(rules_setup.mk))
ifneq ("$$(libs)","")
$$(shell echo " #create lib compiling and linking rules:" >>$$(rules_setup.mk))
$$(shell echo ' libs:=$$(libs)' >>$$(rules_setup.mk))
$$(shell echo ' $$$$(foreach lib,$$(strip $$(libs)),$$$$(eval $$$$(call create_lib_rule,$$$$(lib),$$$$(sort $$$$($$$$(lib)_SRCS)),$$$$($$$$(lib)_LIBS),$$(objdir),$$(srcdir),$$(rules.mk))))' >>$$(rules_setup.mk))
endif
$$(shell echo " " >>$$(rules_setup.mk))
programs:=$$(PROGRAMS)
ifneq ("$$(programs)","")
$$(shell echo " #create program compiling and linking rules:" >>$$(rules_setup.mk))
$$(shell echo ' programs:=$$(programs)' >>$$(rules_setup.mk))
$$(shell echo ' $$$$(foreach program,$$(strip $$(programs)),$$$$(eval $$$$(call create_program_rule,$$$$(program),$$$$(sort $$$$($$$$(program)_SRCS)),$$$$($$$$(program)_LIBS),$$(objdir),$$(srcdir),$$(rules.mk))))' >>$$(rules_setup.mk))
endif
include $(rules_setup.mk)
endef
#project compiling and linking FLAGS:
IPATH:=$($(PRJNAME)_IPATH)
PLPATH:=$($(PRJNAME)_PLPATH)
LLPATH:=$($(PRJNAME)_LLPATH)
PLFLAGS:=$($(PRJNAME)_PLFLAGS)
define initialzie
allobjs:=
allprograms:=
allrules:=
export allgenlibs:=
rules_setup.mks:=
#curent source path directory:
export curdir:=
Filter_make.mks:=
alllibs:=
ifeq ("$(abspath .)","$$(SRCDIR)")
#Running in $(PRJNAME)/src directory,so get subpath from top make.mk
compiling_info:=now running compiling command from $(SRCDIR) path.
include $(SRCDIR)/make.mk
#compiling_path is a subpath list:
compiling_path:=$$(addprefix $(SRCDIR)/,$$(if $$(SUBDIRS),$$(SUBDIRS),$$(allcards_SUBDIRS)))
else
compiling_info:=now running compiling command in a subdirectory:
compiling_path:=$(abspath .)
endif
endef
#the common rules begin**************************************************************
default:
ifeq ("$(MAKECMDGOALS)","create_rule_file")
make.mk:=$(subst $(SRCOBJDIR),$(SRCDIR),$(dir $(RULES.MK)))make.mk
RULES_SETUP.MK:=$(dir $(RULES.MK))rules_setup.mk
make.mk.objs:=
$(foreach mk,$(make.mk),$(eval $(call create_rule_files,$(mk),$(RULES_SETUP.MK),$(RULES.MK))))
create_rule_file:
@echo INFO:Creating $(RULES.MK) file success!
endif
#creating rules.mk file rules:
$(SRCOBJDIR)/%/rules.mk:$(SRCDIR)/%/make.mk
@echo INOF:Begin to create goal file:$@ ,dep file:$<.
@make -f $(NBDIR)/makefile create_rule_file RULES.MK=$@ THEARCH=$(ARCH)
#output directory (for saving object,lib, program files) rules:
$(OUTPUTDIR):
$(if $(wildcard $@),@echo $@ is exist!,mkdir -p $@)
$(ARCHDIR):$(OUTPUTDIR)
$(if $(wildcard $@),@echo $@ is exist!,mkdir -p $@)
$(LIBDIR) $(BINDIR) $(SRCOBJDIR):$(ARCHDIR)
@echo INFO:$(compiling_info)
$(if $(wildcard $@),@echo $@ is exist!,mkdir -p $@)
#the common rules end**************************************************************
#compiling rules begin:(i686 and mips)*********************************************************************
ifneq ("$(filter $(MAKECMDGOALS),$(ARCHS) $(shell ls $(abspath .)))","")
$(shell mkdir -p $(LIBDIR) $(BINDIR) $(SRCOBJDIR))
$(eval $(call initialzie))
#get make.mk file list:
make.mks:=$(sort $(shell find $(compiling_path) -name 'make.mk'))
#Prepare for create rules:
$(foreach mk,$(make.mks),$(eval $(call precreate_rules,$(mk))))
#filter not used make.mk file:
make.mks:=$(filter-out $(Filter_make.mks),$(make.mks))
#get rules.mk file set:
rules.mks:=$(addsuffix rules.mk,$(subst $(SRCDIR),$(SRCOBJDIR),$(dir $(make.mks))))
#all rules file including,if the file not exist, make will create it according rules!
include $(rules.mks)
ifneq ("$(filter $(MAKECMDGOALS),$(shell ls $(abspath .)))","")
#compiling subdirectory processing:
$(MAKECMDGOALS):$(allprograms) $(alllibs)
@echo INFO:compiling $(words $(allobjs)) source files, linking $(words $(alllibs)) libraries.
@echo INFO: compiling in subdirecory finished!
else
ifeq ("$(abspath .)","$(SRCDIR)")
#command running in SRCDIR, so making package after compiling:
$(ARCH):$(allprograms) $(alllibs)
@echo INFO:linking $(words $(allprograms)) program files.
@echo INOF:linking $(words $(alllibs)) libraries.
@echo INFO:compiling $(words $(allobjs)) source files.
else
#command running in subpath of $(SRCDIR)
$(ARCH):$(allprograms) $(alllibs) $(allobjs)
@echo INFO:linking $(words $(allprograms)) program files.
@echo INOF:linking $(words $(alllibs)) libraries.
@echo INFO:compiling $(words $(allobjs)) source files.
endif
endif
$(warning prjname=$(PRJNAME) alllibs=$(alllibs))
default:$(ARCH)
$(allprograms):$(alllibs)
$(alllibs):$(allobjs)
endif
#other goals rules:
.PHONY:pkg help clean cl686 clmips
help:
@echo "gb alli686 :Creating curent project and its dependent project i686 goals."
@echo "gb allmips :Creating curent project and its dependent project mips goals."
@echo "gb mi :Creating curent project i686 and mips goals."
@echo "gb i686 :Creating curent project i686 goals."
@echo "gb mips :Creating curent project mips goals."
@echo "gb :The same as command:gb i686."
@echo "gb mips :The same as command:gb mips."
@echo "gb help :Display make help infomation."
@echo "gb cl686 :Clean i686 compiling output files of current project."
@echo "gb clmips :Clean mips compiling output files of current project."
@echo "gb clean :Clean i686+mips compiling output files of current source directory."
@echo "gb all :i686+mips target and package of current project and its dependent project."
ifneq ("$(filter $(MAKECMDGOALS),$(CLEANS))","")
ifneq ("$(filter $(MAKECMDGOALS),clmips cl686)","")
#cl686, clmips:
ifeq ("$(abspath .)","$(SRCDIR)")
CLEAN_CMDS:=$(if $(wildcard $(ARCHDIR)),rm -rf $(ARCHDIR),)
else
#clean subpath output files:
#clean subdirectory:
$(eval $(call initialzie))
#get make.mk file list:
make.mks:=$(sort $(shell find $(compiling_path) -name 'make.mk'))
#read make.mk files, get those libs and programs file that need to be cleaned.
$(foreach mk,$(make.mks),$(eval $(call precreate_rules,$(mk))))
#check if the files and paths exist:
DELETE_OBJECT_PATH:=$(strip $(wildcard $(subst $(SRCDIR),$(SRCOBJDIR),$(abspath .))))
DELETE_LIB_FILES:=$(strip $(if $(strip $(alllibs)),$(wildcard $(addsuffix *,$(alllibs))),))
DELETE_PROGRAM_FILES:=$(strip $(wildcard $(allprograms)))
#clean rules command:
CLEAN_CMDS:=$(if $(DELETE_OBJECT_PATH),rm -rf $(DELETE_OBJECT_PATH);,) \
$(if $(DELETE_LIB_FILES), cd $(LIBDIR) && rm $(notdir $(DELETE_LIB_FILES)) $(DELETE_PROGRAM_FILES),)
CLEAN_CMDS:=$(if $(CLEAN_CMDS), $(CLEAN_CMDS),)
endif
endif
CLEAN_CMDS:=$(if $(strip $(CLEAN_CMDS)),$(strip $(CLEAN_CMDS)),@echo INFO: $(ARCH) Files are not exist!)
clean:
@echo && make -f $(NBDIR)/makefile cl686 && echo && make -f $(NBDIR)/makefile clmips && echo
$(if $(filter $(abspath . ),$(SRCDIR)),@echo INFO:delete output softlink of $(TOPDIR)/$(PRJNAME) && rm -rf $(TOPDIR)/$(PRJNAME)/localexp/*, @echo)
@echo
cl686 clmips:
@echo INFO:Begin to clean $(ARCH) files...
$(CLEAN_CMDS)
@echo INFO:Clean $(ARCH) files finished!
endif
ifeq ("$(MAKECMDGOALS)","create_rule_file")
make.mk:=$(subst $(SRCOBJDIR),$(SRCDIR),$(dir $(RULES.MK)))make.mk
RULES_SETUP.MK:=$(dir $(RULES.MK))rules_setup.mk
make.mk.objs:=
$(foreach mk,$(make.mk),$(eval $(call create_rule_files,$(mk),$(RULES_SETUP.MK),$(RULES.MK))))
create_rule_file:
@echo INFO:Creating $(RULES.MK) file success!
endif
ifneq ("$(PRJNAME)","")
MKCMD:=make -f $(NBDIR)/makefile
.PHONY:all all686 allmips mi
all:all686 allmips
#compiling dependent project:
ifneq ("$($(PRJNAME)_DEP_PROJECT)","")
#dep project build cmd:
i686_PROJECT_BUILD_CMD:=$(foreach DEP_PRJ,$($(PRJNAME)_DEP_PROJECT), cd $(TOPDIR)/$(DEP_PRJ)/src && $(MKCMD) cl686 && $(MKCMD) all686 && )
#adding current project build cmd:
i686_PROJECT_BUILD_CMD+= cd $(TOPDIR)/$(PRJNAME)/src && $(MKCMD) cl686 && $(MKCMD) -j6 i686
all686:
$(i686_PROJECT_BUILD_CMD)
mips_PROJECT_BUILD_CMD:=$(foreach DEP_PRJ,$($(PRJNAME)_DEP_PROJECT), cd $(TOPDIR)/$(DEP_PRJ)/src && $(MKCMD) clmips && $(MKCMD) allmips && )
mips_PROJECT_BUILD_CMD+= cd $(TOPDIR)/$(PRJNAME)/src && $(MKCMD) clmips && $(MKCMD) -j6 mips
allmips:
$(mips_PROJECT_BUILD_CMD)
else
all686:
cd $(TOPDIR)/$(PRJNAME)/src && $(MKCMD) cl686 && $(MKCMD) -j6 i686
allmips:
cd $(TOPDIR)/$(PRJNAME)/src && $(MKCMD) clmips && $(MKCMD) -j6 mips
endif
mi:
@echo 'Begin to make all target i686 of $(PRJNAME) project:'
cd $(TOPDIR)/$(PRJNAME)/src && $(MKCMD) clean && $(MKCMD) -j6 && $(MKCMD) -j6 mips
endif
2.4 封装脚本文件nb
脚本代码如下:
#假定编译工具部署在/home/nb目录下:
MAKE="make -f/home/nb/makefile"
args=$@
if [ "$1" == "mipsbigpkg" ] || [ "$1" == "i686bigpkg" ] || [ "$1" == "smallpkg" ] || [ "$1" == "help" ] || [ "$1" == "oamcode" ] || [ "$1" == "clean" ] || [ "$1" == "clmips" ] || [ "$1" == "cl686" ] ; then
echo INFO:Command is ${MAKE} $@
${MAKE} $@
else
for arg in ${args}
do
if [ ${arg#-j} != ${arg} ] && [ ${arg#-j} -gt ${jmax} ];then
args=${args/${arg}/-j${jmax}}
fi
done
#以下为实现编译时间计算功能:
echo INOF:compiling command is:$0 ${args}
date_start=`date +%s`
start="INFO:begining time is:"`date +%H:%M:%S`
#真正调用编译命令地方:
${MAKE} ${args}
date_end=`date +%s`
timespan=`echo $date_end-$date_start|bc`
thetime=`echo ${timespan}/3600|bc`:`echo ${timespan}600/60|bc`:`echo ${timespan}`|bc`
echo ${start}
echo INFO:Finished time is:`date +%H:%M:%S`
echo INFO:Running time is: $thetime
fi
3 工具用法
项目src目录下,需要编译项目的src下(包括src),每个子目录需要包含make.mk文件,格式内容如下:
make.mk文件:
prjname/src/make.mk内容:
SUBDIRS:=t1
prjname/src/t1/make.mk内容:
i686_LIBRARIES:=libname
mips_LIBRARIES:=libname
LIBRARIES:=$($(ARCH)_LIBRARIES)
libname_SRCS:=t1.cc
libname_VERSION:=3.0.0
4 应用
该框架已经在多个大型项目中得到使用。
LIBRARIES:=$($(ARCH)_LIBRARIES)
libname_SRCS:=t1.cc
libname_VERSION:=3.0.0
4 应用
该框架已经在多个大型项目中得到使用。
所有评论(0)