http://blog.sina.com.cn/s/blog_6fd68d5f01014bdr.html


基于GNU make的开源大型项目多核并行编译框

 

大型项目编译

    大型项目的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 应用

  该框架已经在多个大型项目中得到使用。

 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐