全部博文(245)
分类: LINUX
2009-05-18 17:10:26
|-- COPYING //这是一个GPL文件 |-- CVS //这是一个版本控制软件的文件夹 |-- Documentation //相关说明文档 |-- Makefile //Makefile文件 |-- Rules.make //Makefile通用规则 |-- arch //与平台板卡相关的文件 |-- drivers //驱动文件 |-- include //头文件 |-- init // 系统初始化文件 |-- lib //库文件 |-- scripts //一些vivi的配置脚本,同时包含有menuconfig的源代码 |-- util //二进制工具,这里有两个工具:imagewrite 和ecc |
上边就是vivi的文件组织结构,有一些文件是与编译无关的,一些说明文档、版本控制文件以及其他一些文件,我们把不需要的文件删除,util这里边的工具用在其他的地方,可以选择性的编译,但这些文件是与vivi的编译无关的,当然,GPL协议是非常重要的,这里不是说GPL不重要,删除只是为了列举与vivi编译有关的文件。下边是精简的文件组织形式:
|-- Makefile //主Makefile |-- Rules.make //通用Makefile规则 |-- arch //与平台板卡相关的文件 |-- drivers //驱动文件 |-- include //头文件 |-- init //初始化文件 |-- lib //库文件 |-- scripts //配置脚本与menuconfig的源码 |
|
|
学习的第一层是优秀的模仿,学会模仿也是一种学习能力。 |
通过上边的操作,我们认为所有的配置已经完成了,应该开始编译工作了,至于编译的流程需要我们看看makefile文件。由于Makefile文件比较长,不方便全部贴在这里。我们分段进行分析。
|
# 版本号 在生成的vivi中,开头的版本号就是有这个地方的变量来决定
VERSION = 0
PATCHLEVEL = 1
SUBLEVEL = 4
# VIVI 这里设置输出版本信息的格式。
VIVIRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)
# ":=" 与"="的区别: ”:=“为直接展开,”=“为递归展开,详细内容看GNU make中文手册6.2.2
# ”:=“在此处会定义一个变量,直接对其赋值,对于引用会直接找到引用的源,表示立即展开
#”:“只是简单的替换,不会直接找到引用的源,在以后,如果引用的源发生变化,此处的变量也会发生变化。表示递归展开
######### 举例 #########
#
# VAR1=TMP1;
# TMP=$(VAR1)
# VAR1=TMP2
# TMP1:=$(VAR1)
#ECHO $(TMP) ===>显示 TMP2
#ECHO $(TMP1)===>显示 TMP1
#
#ARCH是定义体系结构, VIVI此处的定义是说明该VIVI是针对ARM平台
ARCH := arm
# 这里一处make函数的调用,该函数为shell,该行语句的主要作用是设置shell命令解释器
#这条命令的作用是执行函数把结果给变量
#make函数的调用语法为:$()或者${}
#shell函数的作用是”执行命令,把命令的执行结果作为变量的内容“
#COMFIG_SHELL 指定命令解释器
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi)
# 设置当前顶层目录, 该Makefile所在目录 shell函数的用法,把命令pwd的结果赋值给TOPDIR
TOPDIR := $(shell /bin/pwd)
#
# change this to point to the Linux include directory
# 指定LINUX内核的INCLUDE目录,在vivi中,没有起作用,可以删除该语句
#
LINUX_INCLUDE_DIR = /usr/local/arm/2.95.3/include/
# 指定vivi的头文件所在目录
#
VIVIPATH = $(TOPDIR)/include
# 定义本地的编译器 这里指定编译器为gcc
HOSTCC = gcc
#定义本地的编译器的编译参数,vivi的编译需用使用arm-linux-gcc(交叉编译器),那么定义gcc有什么作用?
#解答: 在一次使用make menuconfig的时候,需要使用gcc编译menuconfig选项程序,只为配置服务。
#跳转到scripts/lxdialog
#执行该目录下的make all
# make menuconfig :::---->>
###跳转到scripts/lxdialog
###执行该目录下的make all
###make -C scripts/lxdialog all
###make[1]: Entering directory `/tmp/vivi/scripts/lxdialog' # 跳转入目录
###make[1]: Leaving directory `/tmp/vivi/scripts/lxdialog' # 编译完后,离开目录
###/bin/sh scripts/Menuconfig arch/config.in #执行Menuconfig arch/config.in
###Using defaults found in .config
###Preparing scripts: functions, parsing.............done.
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
#定义交叉编译器的路径,要注意一些公认的定义方法,一般CROSS_COMPILE就是交叉编译器 ARCH就是于体系结构相关的
CROSS_COMPILE = /usr/local/arm/2.95.3/bin/arm-linux-
#CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-redhat-linux-
#
# Include the make variables (CC, etc...)
# 定义工具链 tools chains
#
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
#MD5
MD5SUM = md5sum
# PERL 脚本
PERL = perl
AWK = awk
# 导出前边定义的变量 主要是因为主makefile需要调用很多子makefile,
# 这样导出后,就可以让子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
# 定义就宣告结束了
#下边是具体的编译规则