TX2440 vivi的makefile分析

来源:互联网 发布:魅族flyme解锁软件 编辑:程序博客网 时间:2024/05/29 13:24

#定义表示vivi版本信息的四个变量,vivi版本号为0.1.4
VERSION = 0
PATCHLEVEL = 1
SUBLEVEL = 4

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

#定义目标平台体系结构是ARM.
#"="和":="都是给变量赋值,":="表示立即展开."="表示递归展开.见GUN Make手册P85.
ARCH := arm

#取得当前使用的shell命令解释器,保存在CONFIG_SHELL中,用来执行scripts文件夹中的配置脚本.
#shell函数需要一个命令作为参数,函数的返回结果是这个shell命令的执行结果。见GNU make手册P63

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; /
 else if [ -x /bin/bash ]; then echo /bin/bash; /
 else echo sh; fi ; fi)
  
#取得vivi所在目录名,用到了make的内建函数shell.  
TOPDIR := $(shell /bin/pwd)

#保存头文件所在的目录.可以用Linux内核源码下的include目录,也可以用交叉编译器的include目录.
#例如/usr/local/arm/2.95.3/include
 
# change this to point to the Linux include directory
#
LINUX_INCLUDE_DIR = /usr/local/arm/2.95.3/include/

#vivi头文件所在路径
VIVIPATH           = $(TOPDIR)/include

#定义本地编译器和参数
HOSTCC          = gcc
HOSTCFLAGS      = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

#定义交叉编译器
CROSS_COMPILE   = arm-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:  do-it-all

#wildcard函数的作用是列出当前目录下所有符合参数格式的文件名,见GUN make手册P119
#ifeq关键词的作用是判断参数是否相等,见GUNmake手册P106
#这几条语句的作用是判断当前目录下有没有.config文件,如果有,包含.config;如果没有
#定义一个变量CONFIGURATION为configure,并且do-it-all依赖于config

ifeq (.config,$(wildcard .config))
include .config
else
CONFIGURATION = config
do-it-all: config
endif

#定义do-it-all 依赖于Version和vivi
do-it-all: Version vivi

#标准CFLAGS
# 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

#增加驱动,CONFIG_SERIAL CONFIG_MTD在.config文件中定义,值是y
#"+=",表示给变量追加赋值

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 = /usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3
#ARM_GCC_LIBS = /opt/host/armv4l/lib/gcc-lib/armv4l-redhat-linux/2.95.3

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

#导出变量
export  CPPFLAGS CFLAGS AFLAGS

export  DRIVERS LDFLAGS

#dummy是虚假目标文件
Version: dummy
 @rm -f include/compile.h
 
#依赖文件为:version.h main.o version.o linuxsubdirs 如果$(CONFIGURATION)为空就跳过
#linuxsubdirs是所有子目录下的Makefile编译生成后的目标文件,当所有依赖文件都生成,才往下执行
#编译生成可执行程序vivi-elf 再用objcopy工具将其转换成二进制程序vivi,这个就是vivi镜像
#nm工具的作用是导出目标文件中的符号

vivi: include/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
 $(LD) -v $(LINKFLAGS) /
  $(HEAD) /
  $(CORE_FILES) /
  $(DRIVERS) /
  $(LIBS) /
  -o vivi-elf $(CLIBS)
 $(NM) -v -l vivi-elf > vivi.map
 $(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

#执行make menuconfig,先进入scripts/lxdialog编译
#然后用shell执行scripts/Menuconfig 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)

#$(patsubst )模式替换函数,见GNU make手册P110
#SUBDIRS定义为drivers lib,%代表任意字符串
#这句话作用是把SUBDIRS中以空格分开的字符串加上前缀_dir_

linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))
 
#因为$(SUBDIRS)是依赖文件,是要生成的,当前目录下已经存在drivers和lib
#所以要加上前缀,以免破坏原来的目录,最后要去掉前缀,再进到该目录

#目标文件有两个:_dir_drivers  _dir_lib
#-C是改变目录,分别跳转到drivers和lib目录下,这里要去掉前缀

$(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 $@

#输出这三条语句,重定向到.ver中,然后把.ver重命名为version.h,$@表示目标文件
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
 @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

#$*表示文件名不包含后缀的部分,$<表示第一个依赖文件名
#CFLAGS_KERNEL和PROFILING这两个变量没有定义,编译时跳过

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

#包含Makefile的通用规则
#虽然规则是在最后包含的,但make执行时,最开始分析规则
#见GNU make手册P30 make如何解析makefile文件

include Rules.make

0 0
原创粉丝点击