浅析vivi的Makefile

 

#定义版本信息的四个变量:发行版本号、版本号、补丁程度、次版本号

VERSION = 0              

PATCHLEVEL = 1 

SUBLEVEL = 4   

 

#发行版本号由 版本号:补丁程度:次版本号 组成

VIVIRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)  

 

#定义针对arm平台

#:=”表示直接展开式的变量赋值,ARCH 的值不会随着arm变量的值的改变而改变

ARCH := arm    

 

#定义shell命令解释器的变量CONFIG_SHELLshell函数需要一个shell命令做为参数,

#函数的返回值是这个shell命令的执行结果,make仅仅对它的回返结果进行处理

#这里用来判断bash的路径,并把bash的路径赋值给CONFIG_SHELL

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; /

       else if [ -x /bin/bash ]; then echo /bin/bash; /

       else echo sh; fi ; fi)

#定义顶层目录所在的路径,这里等于当前目录

TOPDIR := $(shell /bin/pwd)

 

#

# change this to point to the Linux include directory

#

LINUX_INCLUDE_DIR       = /opt/host/armv4l/include/

 

#定义vivi头文件所在的路径

VIVIPATH           = $(TOPDIR)/include

 

#定义本地的编译器及其参数

HOSTCC          = gcc

HOSTCFLAGS      = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

 

#定义交叉编译器

CROSS_COMPILE   = /opt/host/armv4l/bin/armv4l-unknown-linux-

#CROSS_COMPILE   = /opt/host/armv4l/bin/armv4l-redhat-linux-

 

#

# Include the make variables (CC, etc...)

#

 

#定义交叉编译工具链

AS              = $(CROSS_COMPILE)as

LD              = $(CROSS_COMPILE)ld

CC              = $(CROSS_COMPILE)gcc

CPP             = $(CC) -E

AR              = $(CROSS_COMPILE)ar

NM              = $(CROSS_COMPILE)nm

STRIP           = $(CROSS_COMPILE)strip

OBJCOPY         = $(CROSS_COMPILE)objcopy

OBJDUMP         = $(CROSS_COMPILE)objdump

MAKEFILES       = $(TOPDIR)/.config

MD5SUM              = md5sum

PERL            = perl

AWK              = awk

 

#导出前面定义的变量,给子Makefile使用

export  VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE /

        CONFIG_SHELL TOPDIR VIVIPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC /

       CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES MD5SUM PERL AWK

 

#第一条规则,生成最终目标all,依赖do-it-all

#all并没有定义生成规则

all:   do-it-all                                     

 

#wildcard 函数作用是列出当前目录下所有符合参数格式的文件名

#ifeq 判断参数是否相等

#整段的作用是判断当前目录下有没有.config这个文件,若有,则包含.config这个文件;

#若无,则定义变量CONFIGURATIONconfig,并且do-it-all依赖于config

ifeq (.config,$(wildcard .config))

include .config

else

CONFIGURATION = config

do-it-all:   config

endif

 

#定义do-it-all依赖于Version vivi,若上段无.config这个文件,则还多依赖了config

#do-it-all没有生成规则

do-it-all:   Version vivi 

 

#

# standard CFLAGS

#

 

#定义预处理器的参数

CPPFLAGS := -I$(VIVIPATH) -I$(LINUX_INCLUDE_DIR)

#CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 /

#          -fomit-frame-pointer -fno-strict-aliasing -fno-common

#定义编译器的参数

CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fPIC -fomit-frame-pointer

#定义汇编器的参数

AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)

 

#定义核心文件

CORE_FILES = init/main.o init/version.o lib/lib.o

LIBS            := lib/priv_data/priv_data.o

#定义子目录

SUBDIRS         = drivers lib

 

#定义驱动,“+=”表示变量追加

DRIVERS-y :=

DRIVERS-$(CONFIG_SERIAL) += drivers/serial/serial.o

DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtd.o

DRIVERS := $(DRIVERS-y)

 

#定义make clean 要删除的文件

CLEAN_FILES = /

       vivi-elf /

       vivi /

       vivi.nm /

       vivi.map

 

#

# Location of the gcc arm libs.

#

#指定库的路径

ARM_GCC_LIBS   = /opt/host/armv4l/lib/gcc-lib/armv4l-unknown-linux/2.95.2

#ARM_GCC_LIBS = /opt/host/armv4l/lib/gcc-lib/armv4l-redhat-linux/2.95.3

 

#定义OBJCOPY的参数

OBJCOPYFLAGS = -R .comment -R .stab -R .stabstr

 

#指定库及库搜索路径

CLIBS = -L$(ARM_GCC_LIBS) -lgcc -lc

#指定链接器命令行参数

LINKFLAGS = -Tarch/vivi.lds -Bstatic

 

#定义执行make distclean 时要删除的文件

DISTCLEAN_FILES = /

       include/autoconf.h include/version.h /

       scripts/lxdialog/*.o scripts/lxdialog/lxdialog /

       .menuconfig.log /

       .config .config.old TAGS tags

 

#包含结构的Makefile

include arch/Makefile

 

#导出变量CPPFLAGS CFLAGS AFLAGS

export  CPPFLAGS CFLAGS AFLAGS

 

#导出变量DRIVERS LDFLAGS

export  DRIVERS LDFLAGS

 

#Version的规则,删除include/compile.h,“@”表示命令不回显

Version: dummy                                

       @rm -f include/compile.h

 

#生成vivi的规则,依赖于include/version.h $(CONFIGURATION) init/main.o init/version.o #linuxsubdirs

vivi: include/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs

       $(LD) -v $(LINKFLAGS) /

              $(HEAD) /

              $(CORE_FILES) /

              $(DRIVERS) /

              $(LIBS) /

              -o vivi-elf $(CLIBS)

#列出目标文件vivi-elf的符号清单到vivi.map文件中

       $(NM) -v -l vivi-elf > vivi.map

#elf格式的可执行程序    vivi-elf 转换成待烧写的镜像文件 vivi

       $(OBJCOPY) -O binary -S vivi-elf vivi $(OBJCOPYFLAGS)

 

oldconfig:

       $(CONFIG_SHELL) scripts/Configure -d arch/config.in

 

config:

       $(CONFIG_SHELL) scripts/Configure arch/config.in

 

menuconfig: include/version.h

       $(MAKE) -C scripts/lxdialog all

       $(CONFIG_SHELL) scripts/Menuconfig arch/config.in

 

clean:

       find . /( -name '*.o' -o -name core -o -name ".*.flags" /) -type f -print /

       | grep -v lxdialog/ | xargs rm -f

       rm -f $(CLEAN_FILES)

 

distclean: clean

       rm -f $(DISTCLEAN_FILES)

 

#linuxsubdirs的生成规则,由此进到子目录,执行子目录的Makefile

#patsubst字符替换函数,用在这里是把drivers lib 替换成_dir_drivers _dir_lib

linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))

 

#生成_dir_drivers _dir_lib的规则

#-C”表示改变目录,$(patsubst _dir_%, %, $@)表示执行完后把生成的目标文件替换成#drivers lib

#名字来回替换的原因:driverlib是子目录的名字,已经存在于文件中,这样就不会执行#Makefile中的规则

#因此,为了不和它们混淆,产生不必要的麻烦,就对目标的名字进行了替换。

$(patsubst %, _dir_%, $(SUBDIRS)) : include/version.h

       $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@)

 

$(TOPDIR)/include/version.h: include/version.h

$(TOPDIR)/include/compile.h: include/compile.h

 

include/compile.h: $(CONFIGURATION) include/version.h

       @echo -n /#define UTS_VERSION /"/#$(VIVIRELEASE) > .ver

       @if [ -f .name ]; then  echo -n /-`cat .name` >> .ver; fi

       @echo ' '`date`'"' >> .ver

       @echo /#define VIVI_COMPILE_TIME /"`date +%T`/" >> .ver

       @echo /#define VIVI_COMPILE_BY /"`whoami`/" >> .ver

       @echo /#define VIVI_COMPILE_HOST /"`hostname`/" >> .ver

       @if [ -x /bin/dnsdomainname ]; then /

          echo /#define VIVI_COMPILE_DOMAIN /"`dnsdomainname`/"; /

        elif [ -x /bin/domainname ]; then /

          echo /#define VIVI_COMPILE_DOMAIN /"`domainname`/"; /

        else /

          echo /#define VIVI_COMPILE_DOMAIN ; /

        fi >> .ver

       @echo /#define VIVI_COMPILER /"`$(CC) $(CFLAGS) -v 2>&1 | tail -1`/" >> .ver

       @mv -f .ver $@

 

#把以下三句话写到include/version.h,其中的“@”表示不回显,“/”表示它后面的“#”不是注释

##define VIVI_RELEASE /"$(VIVIRELEASE)/"

##define VIVI_VERSION_CODE `expr $(VERSION) //* 65536 + $(PATCHLEVEL) //* 256 + $(SUBLEVEL)`

##define VIVI_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))

include/version.h:

       @echo /#define VIVI_RELEASE /"$(VIVIRELEASE)/" > .ver

       @echo /#define VIVI_VERSION_CODE `expr $(VERSION) //* 65536 + $(PATCHLEVEL) //* 256 + $(SUBLEVEL)` >> .ver

       @echo '#define VIVI_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver

#.ver 改名成include/version.h

       @mv -f .ver $@

 

init/version.o: init/version.c include/compile.h

       $(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c

 

#生成main.o的规则

init/main.o: init/main.c

       $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<

 

TAGS: dummy

       etags `find include -name '*.h'`

       find $(SUBDIRS) init -name '*.[ch]' | xargs etags -a

 

# Exuberant ctags works better with -I

tags: dummy

       CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; /

       ctags $$CTAGSF `find include -name '*.h'` && /

       find $(SUBDIRS) init -name '*.[ch]' | xargs ctags $$CTAGSF -a

 

%: ./arch/def-configs/%

       $(MAKE) distclean

       cp arch/def-configs/$* ./.config -f

       $(MAKE) oldconfig

       $(MAKE)

      

 

ifdef CONFIGURATION

..$(CONFIGURATION):

       @echo

       @echo "You have a bad or nonexistent" .$(CONFIGURATION) ": running 'make" $(CONFIGURATION)"'"

       @echo

       $(MAKE) $(CONFIGURATION)

       @echo

       @echo "Successful. Try re-making (ignore the error that follows)"

       @echo

       exit 1

 

dummy:

 

else

 

dummy:

 

endif

 

#包含make的规则

#为什么能写在最后呢,而不是写在开头呢?

#因为make分两阶段执行.

#第一阶段:读取所有的makefile文件(包括“MAKIFILES”变量指定的、指示符“include#指定的、

#以及命令行选项“-f(--file)”指定的makefile文件),内建所有的变量、明确规则和隐含规

#则,

#并建立所有目标和依赖之间的依赖关系结构链表。

#第二阶段:根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新,并使用对

#应的规则来重建这些目标。

include Rules.make

 

 

 =========================================================================

附加Rules.make文件:

#

# This file contains rules which are shared between multiple Makefiles.

#

 

#

# False targets.

#

#定义伪目标dummy

.PHONY: dummy

 

#

# Special variables which should not be exported

#

#不导出变量,防止影响其它文件的同名变量

unexport EXTRA_AFLAGS

unexport EXTRA_CFLAGS

unexport EXTRA_LDFLAGS

unexport EXTRA_ARFLAGS

unexport SUBDIRS

unexport SUB_DIRS

unexport ALL_SUB_DIRS

unexport O_TARGET

 

unexport obj-y

unexport obj-n

unexport obj-

unexport export-objs

unexport subdir-y

unexport subdir-m

unexport subdir-n

unexport subdir-

 

#

# Get things started.

#

first_rule: sub_dirs

       $(MAKE) all_targets

 

both-m          := $(filter $(mod-subdirs), $(subdir-y))

SUB_DIRS     := $(subdir-y)

ALL_SUB_DIRS    := $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-))

 

 

#

# Common rules

#

 

%.s: %.c

       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -S $< -o $@

 

%.i: %.c

       $(CPP) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) $< > $@

 

%.o: %.c

       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $<

       @ ( /

           echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@))))' ; /

           echo 'FILES_FLAGS_UP_TO_DATE += $@' ; /

           echo 'endif' /

       ) > $(dir $@)/.$(notdir $@).flags

 

%.o: %.s

       $(AS) $(AFLAGS) $(EXTRA_CFLAGS) -o $@ $<

 

%.s: %.S

       $(CPP) $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$@) $< > $@

 

%.o: %.S

       $(CC) $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$@) -c -o $@ $<

 

 

%.lst: %.c

       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<

       $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)

#

#

#O_TARGET L_TARGET在子Makefile中定义

all_targets: $(O_TARGET) $(L_TARGET)

 

#

# Rule to compile a set of .o files into one .o file

#

ifdef O_TARGET

$(O_TARGET): $(obj-y)

       rm -f $@

    ifneq "$(strip $(obj-y))" ""

       $(LD) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^)

    else

#打包成目标文件

       $(AR) rcs $@

    endif

       @ ( /

           echo 'ifeq ($(strip $(subst $(comma),:,$(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(EXTRA_LDFLAGS) $$(obj-y))))' ; /

           echo 'FILES_FLAGS_UP_TO_DATE += $@' ; /

           echo 'endif' /

       ) > $(dir $@)/.$(notdir $@).flags

endif # O_TARGET

 

#

# Rule to compile a set of .o files into one .a file

#

ifdef L_TARGET

$(L_TARGET): $(obj-y)

       rm -f $@

       $(AR) $(EXTRA_ARFLAGS) rcs $@ $(obj-y)

       @ ( /

           echo 'ifeq ($(strip $(subst $(comma),:,$(EXTRA_ARFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(EXTRA_ARFLAGS) $$(obj-y))))' ; /

           echo 'FILES_FLAGS_UP_TO_DATE += $@' ; /

           echo 'endif' /

       ) > $(dir $@)/.$(notdir $@).flags

endif

 

 

#

# This make dependencies quickly

#

fastdep: dummy

       $(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS) -- $(wildcard *.[chS]) > .depend

ifdef ALL_SUB_DIRS

       $(MAKE) $(patsubst %,_sfdep_%,$(ALL_SUB_DIRS)) _FASTDEP_ALL_SUB_DIRS="$(ALL_SUB_DIRS)"

endif

 

ifdef _FASTDEP_ALL_SUB_DIRS

$(patsubst %,_sfdep_%,$(_FASTDEP_ALL_SUB_DIRS)):

       $(MAKE) -C $(patsubst _sfdep_%,%,$@) fastdep

endif

 

      

#

# A rule to make subdirectories

#

#sort按字母排序函数,在这里先把$(SUB_DIRS)替换成_subdir_$(SUB_DIRS)的形式,再按

#字母顺序排序

subdir-list = $(sort $(patsubst %,_subdir_%,$(SUB_DIRS)))

sub_dirs: dummy $(subdir-list)

 

ifdef SUB_DIRS

$(subdir-list) : dummy

       $(MAKE) -C $(patsubst _subdir_%,%,$@)

endif

 

#

# A rule to do nothing

#

dummy:

 

#

# This is useful for testing

#

script:

       $(SCRIPT)

 

#

# include dependency files if they exist

#

ifneq ($(wildcard .depend),)

include .depend

endif

 

ifneq ($(wildcard $(TOPDIR)/.hdepend),)

include $(TOPDIR)/.hdepend

endif

 

#

# Find files whose flags have changed and force recompilation.

# For safety, this works in the converse direction:

#   every file is forced, except those whose flags are positively up-to-date.

#

FILES_FLAGS_UP_TO_DATE :=

 

# For use in expunging commas from flags, which mung our checking.

comma = ,

 

FILES_FLAGS_EXIST := $(wildcard .*.flags)

ifneq ($(FILES_FLAGS_EXIST),)

include $(FILES_FLAGS_EXIST)

endif

 

FILES_FLAGS_CHANGED := $(strip /

    $(filter-out $(FILES_FLAGS_UP_TO_DATE), /

       $(O_TARGET) $(L_TARGET) $(active-objs) /

       ))

 

# A kludge: .S files don't get flag dependencies (yet),

#   because that will involve changing a lot of Makefiles.  Also

#   suppress object files explicitly listed in $(IGNORE_FLAGS_OBJS).

#   This allows handling of assembly files that get translated into

#   multiple object files (see arch/ia64/lib/idiv.S, for example).

FILES_FLAGS_CHANGED := $(strip /

    $(filter-out $(patsubst %.S, %.o, $(wildcard *.S) $(IGNORE_FLAGS_OBJS)), /

    $(FILES_FLAGS_CHANGED)))

 

ifneq ($(FILES_FLAGS_CHANGED),)

$(FILES_FLAGS_CHANGED): dummy

endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值