makefile4vivi-top makefile

个人在看VIVI的makefile时的一些认识(部分内容已经被我修改,初步的草稿,还将继续修正):

 

 

总MAKEFILE最终目的就是要生成VIVI,所以从生成VIVI的规则开始分析。前面的部分都是在后面规则里面需要用到的定义。

#版本信息和体系结构

VERSION = 0
PATCHLEVEL = 1
SUBLEVEL = 4
VIVIRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)

 

ARCH := arm

 

#选择相应的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    = /usr/local/arm/2.95.3/include

#VIVI的头文件路径
VIVIPATH           = $(TOPDIR)/include

 

 

 

#一系列的工具和编译选项

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

CROSS_COMPILE   = /usr/local/arm/2.95.3/bin/arm-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

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

 

 

 

#总的依赖为vivi,version,.config,如果.config存在那么将其包含,利用其中的配置信息,如果不存在那么需要通过依赖建立这个文件,

#所以在不存在时定义CONFIGURATION = config,并使CONFIGURATION成为依赖。

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

#从下面分析来看这一句并不是必须的,在下面的vivi的生成规则中已经包含了对$CONFIGURATION的依赖,可以执行config操作。
endif

 

 

#MAKE入口点

all:     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

#normal flags
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fPIC -fomit-frame-pointer
#symbol table make up
#CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fPIC -fomit-frame-pointer -ggdb

AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)

#
# Location of the gcc arm libs.
#

ARM_GCC_LIBS    = /usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3

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

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

#laputa symbolic  这里的.lds文件需要编写
LINKFLAGS = -Tarch/vivi.lds -Bstatic


CORE_FILES    = init/main.o init/version.o lib/lib.o
LIBS            := lib/priv_data/priv_data.o
SUBDIRS         = drivers lib

#下面这个写法我觉得很好,如果配置文件中有相应的配置,那么该配置就是y,对应的驱动被追加,将最后的追加结果给驱动。

DRIVERS-y :=
DRIVERS-$(CONFIG_SERIAL) += drivers/serial/serial.o
DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtd.o
DRIVERS := $(DRIVERS-y)

 

#清除操作对应的文件

#最终生成的一些文件

CLEAN_FILES = /
    vivi-elf /
    vivi /
    vivi.nm /
    vivi.map


#配置过程生成的一些文件
DISTCLEAN_FILES = /
    include/autoconf.h include/version.h /
    scripts/lxdialog/*.o scripts/lxdialog/lxdialog /
    .menuconfig.log /
    .config .config.old

 

#由于在生成最终文件的时候要用到arch文件夹中的目标文件,调用其makefile进行生成

include arch/Makefile

export  CPPFLAGS CFLAGS AFLAGS

export  DRIVERS LDFLAGS

#因为compile.h 中保存的是最后一次编译过程中生成的时间,工具等信息,它被include/version.h调用,需要更新,所以将其删除

Version: dummy
    @rm -f include/compile.h

 

#生成最终vivi文件的规则,可以看一下需要的依赖有没有全部有相应生成的地方

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)

 

#这里对以上用到各文件进行一个分析:HEAD在arch目录下定义,上面已经include了相应的makefile进行规则定义,打开看一下可知主

#要是根据配置文件(主Makefile包含了.config,这样看来先make config一下比较稳妥)追加了一些与体系结构等有关的编译规则、定义了MACHINE PROCESSOR TEXTADDR,修改了SUBDIRS #CORE_FILE CLEAN_FILES 使其包含了这个目录下相关的文件而

#head.o的生成则是由主Makefile中include Rules.make来完成。

#其中vivi:$(HEAD)  arch/vivi.lds  arch/vivi.lds: $(LDSCRIPT) dummy  @sed s/TEXTADDR/$(TEXTADDR)/ $(LDSCRIPT) >$@

#使得vivi包含了对$(HEAD)的依赖,由于其中的连接方式等可能与总的vivi那边不大一样,所以写在了子Makefile中。

#总的来看该子makefile主要的任务是根据CPU的相关信息来调整总操作和选项。

 

 

#几种config操作:通过相应的脚本和config.in文件中的选择与用户交互完成.config文件生成。以config操作为例,其中

#scripts/Configure脚本是模仿LINUX的,打开看一下可知config.in需要根据自己的需要进行修改,主要功能是提醒用户可以选择的配置

#以及完成相应配置的保存。主要有如:comment、bool、hex等这些语句来提示和保存信息。最后有source lib/priv_data/Config.in
#source drivers/serial/Config.in source drivers/mtd/Config.in source lib/Config_cmd.in几个配置选择文件的调入。打开看下这些子config.in可知,它们又调入了更下一层的config.in文件,这样要提示用户一个新的可配置的模块时,只需要写好该模块自己的config.in提示文件,并在它所属的上一层config.in中用source调用即可。

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)

 

#执行其他子目录下的makefile

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

#使用patsubst避免目标和操作的文件重名

$(patsubst %, _dir_%, $(SUBDIRS)) : include/version.h
    $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@)

 

#还没有看明白以下两句有何精髓...可能是在别的makefile中有用到下面两个目标
$(TOPDIR)/include/version.h: include/version.h
$(TOPDIR)/include/compile.h: include/compile.h

#在前面为了产生新的version.h,前面已经通过make Version或者通过make入口后删除了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:
    @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

init/main.o: init/main.c
    $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<

 

#如果需要选择默认的配置文件来复制生成.config并且自动执行后面操作生成vivi,默认配置文件里面定义了一种配置模式,可以打开看一下

#是否能满足需要

%: ./arch/def-configs/%
    $(MAKE) distclean
    cp arch/def-configs/$* ./.config -f
    $(MAKE) oldconfig
    $(MAKE)
   
#通过make ..config 可以查看是否存在.config文件,如果不存在将会给出相关提示。
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中只需要给出依赖关系即可

include Rules.make

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值