二、主目录 Makefile 分析(1)
2.1 uboot 版本号
uboot 的版本号分三个级别:
- VERSION:主版本号
- PATCHLEVEL:次版本号,为补丁级别
- SUBLEVEL:再次版本号
- EXTRAVERSION:附加版本信息。这个一般使给自己用的,可以定义为字符串如”JH“
- U_BOOT_VERSION:版本号
- VERSION_FILE:版本文件变量
这4个用.分隔开共同构成了最终的版本号。
Makefile 中的版本号最终生成了一个变量 UBOOTVERSION,这个变量记录了 Makefile 中配置的版本号。
include/version_autogenerated.h文件是编译过程中自动生成的一个文件,所以源目录中没有,但是编译过后的uboot中就有了。它里面的内容是一个宏定义,宏定义的值内容就是我们在Makefile中配置的uboot的版本号。
24-29行:
VERSION =
PATCHLEVEL =
SUBLEVEL =
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
obj 变量定义在后面, makefile 中若是有等号,则变量取用最后定义的,若是源码目录编译,没指定O的值的话,obj为空,则放在 include 文件夹下
2.2 HOSTARCH 和 HOSTOS
HOSTARCH:主机CPU架构;HOST是主机,就是当前做开发用的CPU或电脑;ARCH是架构,表示CPU的架构。
HOSTOS:主机的操作系统
这两个变量是用 export 导出的环境变量,
uname 是shell 脚本命令 uname -m 命令是得到CPU的类型
uname -s 显示操作系统类型
sed -e:以选项中的指定的 cript 来处理输入的文本文件
tr命令可以对来自标准输入的字符进行替换、压缩和删除。
tr '[:upper:]' '[:lower:]':将大写字符转换为小写字符
31-42行
HOSTARCH := $(shell uname -m | \
sed -e s/i./i386/ \
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/powerpc/ppc/ \
-e s/macppc/ppc/) HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/') export HOSTARCH HOSTOS
2.3 VENDOR
VENDOR= #表示开发商
2.4 编译方法
U-boot 的编译过程可以支持向一个自己定义的路径生成最终的目标文件。这里提供两种方法:
- 原地编译:通过在终端执行命令make O=/dir(即你指定的生成的目标文件的存放目录)
- 编译复杂项目,Makefile提供2种编译管理方法。默认情况下是当前文件夹中的.c文件,编译出来的.o文件会放在同一文件夹下。这种方式叫原地编译。原地编译的好处就是处理起来简单。
- 原地编译有一些坏处:
- 第一,污染了源文件目录。
- 第二的缺陷就是一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。
- 为了解决以上2种缺陷,uboot支持单独输出文件夹方式的编译(linux kernel也支持,而且uboot的这种技术就是从linux kernel学习来的)
- 单独输出文件夹编译:通过设置环境变量来指定目标文件存放目录,如下举例所示:'export BUILD_DIR=/tmp/build';make
- 单独输出文件夹编译也可以写成MAKEALL脚本,然后执行MAKEALL,如下:'export BUILD_DIR=/tmp/build';'./MAKEALL'
- 基本思路就是在编译时另外指定一个输出目录,将来所有的编译生成的.o文件或生成的其他文件全部丢到那个输出目录下去。源代码目录不做任何污染,这样输出目录就承载了本次配置编译的所有结果。
- 具体用法:默认的就是原地编译。如果需要指定具体的输出目录编译则有2种方式来指定输出目录。
- 第一种:make O=输出目录
- 第二种:export BUILD_DIR=输出目录 然后再make
- 如果两个都指定了(既有BUILD_DIR环境变量存在,又有O=xx),则O=xx具有更高优先级,听他的。
命令行'O='设置会覆盖环境变量BUILD_DIR的设置
如果都不采用上面两种方法,那么目标文件放到源码顶层目录,也就是U-BOOT顶层目录
代码 69 到 98行
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR) # Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}) # Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),) OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD :=
export REMOTE_BUILD
endif
100到110行,实现 编译目录和源代码目录不相同的时候执行 obj赋值,如果是在源码目录赋值,则 obj 和 src 都为空
- OBJTREE:编译出的.o文件存放的目录的根目录。在默认编译下,OBJTREE等于当前目录;在O=xx编译下,OBJTREE就等于我们设置的那个输出目录。
- SRCTREE: 源码目录,其实就是源代码的根目录,也就是当前目录。
- TOPDIR:若是 make -O 则此值为 SRCTREE,也就是源码根目录
- LNDIR:链接目录,也是需要 O=XX 编译,此情况下为我们输出的目录,也就是 OBJTREE
# $(obj) and (src) are defined in config.mk but here in main Makefile
# we also need them before config.mk is included which is the case for
# some targets like unconfig, clean, clobber, distclean, etc.
ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src
执行完毕后,将 obj src 值输出成环境变量,供 u-boot 其他文件中调用
总结:在默认编译下,OBJTREE和SRCTREE相等;在O=xx这种编译下OBJTREE和SRCTREE不相等。Makefile中定义这两个变量,其实就是为了记录编译后的.o文件往哪里放,就是为了实现O=xx的这种编译方式的。
2.5 MKCONFIG
代码在 92 93 行:
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
Makefile中定义的一个变量(在这里定义,在后面使用),它的值就是我们源码根目录下面的mkconfig。这个mkconfig是一个脚本,这个脚本就是uboot配置阶段的配置脚本。
2.6 编译选项---CROSS_COMPILE
- CROSS_COMPILE 是定义交叉编译工具链的前缀的。
- 定义这些前缀是为了在后面用(用前缀加上后缀来定义编译过程中用到的各种工具链中的工具)。
- 我们把前缀和后缀分开还有一个原因就是:在不同CPU架构上的交叉编译工具链,只是前缀不一样,后缀都是一样的。
- 因此定义时把前缀和后缀分开,只需要在定义前缀时区分各种架构即可实现可移植性。
代码在 112 到 161 行:
#########################################################################
# 此句判断有没有生成include/config.mk文件,有这个文件则makefile 认为是配置过了 make xxx_defconfig。
ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk)) # load ARCH, BOARD, and CPU configuration,包含 include/config.mk 文件
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),ppc)
CROSS_COMPILE =
else
ifeq ($(ARCH),ppc)
CROSS_COMPILE = powerpc-linux-
endif
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
ifeq ($(ARCH),i386)
ifeq ($(HOSTARCH),i386)
CROSS_COMPILE =
else
CROSS_COMPILE = i386-linux-
endif
endif
ifeq ($(ARCH),mips)
CROSS_COMPILE = mips_4KC-
endif
ifeq ($(ARCH),nios)
CROSS_COMPILE = nios-elf-
endif
ifeq ($(ARCH),nios2)
CROSS_COMPILE = nios2-elf-
endif
ifeq ($(ARCH),m68k)
CROSS_COMPILE = m68k-elf-
endif
ifeq ($(ARCH),microblaze)
CROSS_COMPILE = mb-
endif
ifeq ($(ARCH),blackfin)
CROSS_COMPILE = bfin-elf-
endif
ifeq ($(ARCH),avr32)
CROSS_COMPILE = avr32-
endif
endif
endif export CROSS_COMPILE
- wildcard:在规则中,通配符会被自动展开。 但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“ wildcard”,它的用法是: $(wildcard PATTERN...) 。
- 在 Makefile 中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空。
- 此段代码是先判断 include/config.mk 是否存在,若存在,则在主 Makefile 中包含此文件,导出 config.mk 中的变量ARCH CPU BOARD VENDOR SOC
- include/config.mk 不是源码自带的(没有编译过的源码目录下是找不到这个文件的),要在配置过程(make xx_defconfig)中才会生成这个文件。因此这个文件的值和我们配置过程有关,是由配置过程根据我们的配置自动生成的。
- 接下来,判断编译,即 make 的时候是否传入参数 CROSS_COMPILE,如果没有定义,则在主Makefile 中定义CROSS_COMPILE 环境变量,最后导出 CROSS_COMPILE
- ARCH 变量:这是 include/config.mk 中导出的,也就是在我们的配置过程中生成的,ARCH的意义是定义当前编译的目标CPU的架构
二、主目录 Makefile 分析(1)的更多相关文章
- 二、主目录 Makefile 分析(3)
2.8 编译选项 重新回到 主 makefile 中执行 2.8.1 u-boot 的编译顺序 代码166 到 189 行,这些是 u-boot 文件编译的顺序,由代码可以看到,首先是从cpu/$( ...
- 二、主目录 Makefile 分析(2)
2.7 编译选项---config.mk 代码 163 164 行 # load other configuration include $(TOPDIR)/config.mk 此段就是包含顶层目录下 ...
- LibOpenCM3(二) 项目模板 Makefile分析
目录 LibOpenCM3(一) Linux下命令行开发环境配置 LibOpenCM3(二) 项目模板 Makefile分析 LibOpenCM3 项目模板 项目模板地址: https://githu ...
- Android发展的一个重要方面Makefile分析
Android发展的一个重要方面Makefile分析 随着移动互联网的发展,移动开发也越来越吃香了.眼下最火的莫过于android.android是什么就不用说了,android自从开源以来,就受到非 ...
- uboot 主Makefile分析
一. Makefile 配置 1.1. make xxx_config 1.1.1. 笔者实验时是make x210_sd_config a. x210_sd_config是Makefile下的一个目 ...
- makefile 分析 -- 内置变量及自动变量
makefile 分析1 -p 选项,可以打印出make过程中的数据库, 下面研究一下内置的变量和规则. -n 选项, 只运行,不执行, -d 选项,相当于--debug=a, b(basic), ...
- uboot主Makefile分析(t配置和编译过程详解)
1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_c ...
- uboot主Makefile分析
VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(S ...
- (二)u-boot2013.01.01 for TQ210:《Makefile分析》
当时写的时候看的是2012-10版本的,但是略对比了一遍和2013.01.01没什么改动,所以这不影响对2013.01.01版本的makefile的理解.本文比较侧重于语法句意的分析,框 ...
随机推荐
- webpack4.x相关笔记整理
概念 Webpack是一个模块打包机,它可以将我们项目中的所有js.图片.css等资源,根据其入口文件的依赖关系,打包成一个能被浏览器识别的js文件.能够帮助前端开发将打包的过程更智能化和自动化. W ...
- Oracle中rownum和rowid的理解
rownum,rowid都叫伪列. 但是,rownum是逻辑上的编号,且其值总是从1开始,每行的rounum不是固定的.而rowid是“物理”编号.若数据库文件没有移动,则每行的 rowid一般是固定 ...
- Windows 下vim的配置文件_vimrc
set nocompatible source $VIMRUNTIME/vimrc_example.vim source $VIMRUNTIME/mswin.vim behave mswin set ...
- BZOJ2152[国家集训队]聪聪可可——点分治
题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...
- BZOJ2135 刷题计划(贪心+二分)
相邻数作差后容易转化成将这些数最多再切m刀能获得的最小偏差值.大胆猜想化一波式子可以发现将一个数平均分是最优的.并且划分次数越多能获得的偏差值增量越小.那么就可以贪心了:将所有差扔进堆里,每次取出增量 ...
- python基础成长之路四-基础数据类型方法
1,程序开发三大流程: 顺序--从上向下,顺序执行代码 分支--根据条件判断,决定执行代码的分支 循环--让特定的代码重复执行 2,whlie循环语句: Break 某一条件满足时,退出循环,不在执行 ...
- 从TensorFlow到PyTorch:九大深度学习框架哪款最适合你?
开源的深度学习神经网络正步入成熟,而现在有许多框架具备为个性化方案提供先进的机器学习和人工智能的能力.那么如何决定哪个开源框架最适合你呢?本文试图通过对比深度学习各大框架的优缺点,从而为各位读者提供一 ...
- Cgod省选的爆零日记
声明 虽然是日记,但博主太咕咕咕了,所以可能会鸽掉. 3.11 辣鸡杭二的机子,卡我常数,削我分数. 他们那边的机子好像比我们慢四倍的样子? 开局刚\(T3\),分数全靠骗. \(yy\)许久\(GG ...
- 【BZOJ3202】项链(莫比乌斯反演,Burnside引理)
[BZOJ3202]项链(莫比乌斯反演,Burnside引理) 题面 BZOJ 洛谷 题解 首先读完题目,很明显的感觉就是,分成了两个部分计算. 首先计算本质不同的珠子个数,再计算本质不同的项链个数. ...
- 本地Git与GitHub服务器建立连接(SSH方式通信)
简介 Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要 ...