2.7 编译选项---config.mk

  代码 163 164 行

 # load other configuration
include $(TOPDIR)/config.mk

  此段就是包含顶层目录下的 config.mk,在顶层的  config.mk 中包含了编译选项。

2.7.1 topdir/config.mk 分析

  代码 26 到 45行:

 ifneq ($(OBJTREE),$(SRCTREE))
ifeq ($(CURDIR),$(SRCTREE))
dir :=
else
dir := $(subst $(SRCTREE)/,,$(CURDIR))
endif obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)
src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/) $(shell mkdir -p $(obj))
else
obj :=
src :=
endif # clean the slate ...
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =
  1. 代码首先判断 目标存放目录是否不等于源码目录,若不等于,则执行分支语句,等于 则不执行。
  2. 执行分支语句,判断当前目录是否等于源码目录,若等于则将 dir 置空,否则,把$(CURDIR)中的$(SRCTREE)/替换称空,然后赋给dir
  3. 执行完之后,如果 dir 不为空,则把$(OBJTREE)/$(dir)/赋给obj,否则把直接把$(OBJTREE)/赋给obj
  4. 如果src不为空,则把$(SRCTREE)/$(dir)/赋给src,否则把$(SRCTREE)/赋给src
  5. 通过一个shell 函数创建 obj 路径,obj 的路径为 $(OBJTREE)/$(dir)/ 或 $(OBJTREE)/
  6. 若是目标目录和源码目录相同,则 obj 和 src 都为空
  7. 最后清除三个 编译选项 标志

  PLATFORM_RELFLAGS、PLATFORM_CPPFLAGS 和 PLATFORM_LDFLAGS 这三个变量被置空,之后会被赋值上编译参数,接下来的 54 到 92 行都是给三个编译选项赋值参数:

  63 到 70行,是架构为ARM的赋值,但里面的 CROSS_COMPILE 不能匹配,不会执行

 ifeq ($(ARCH),arm)
ifeq ($(CROSS_COMPILE),powerpc-netbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
endif

  76 到 92 行,会根据前面#include/config.mk 导出的环境变量参数来包含相应的 config.mk 文件

 ifdef    ARCH
sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules
endif
ifdef CPU
sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules
endif
ifdef SOC
sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk # include SoC specific rules
endif
ifdef VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif
ifdef BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif

  根据前面的参数进行展开即可

  96 到 106 行,是给几个参数赋值,HOSTCC 赋值为 gcc,HOSTCFLAGS 和 HOSTSTRIP

  CONFIG_SHELL,涉及到  shell 语法和命令

  • if 语句的 -x 参数为测试文件对当前用户是都可执行
  • 再看一下 shell  的特殊变量:
    • $0      当前脚本的文件名
    • $n      传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
    • $#      传递给脚本或函数的参数个数。
    • $*      传递给脚本或函数的所有参数。
    • $@      传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
    • $?      上个命令的退出状态,或函数的返回值。一般情况下,大部分命令执行成功会返回 0,失败返回 1。
    • $$      当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
    • $* 和 $@ 的区别 : 
      1. $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
      2. 但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
 CONFIG_SHELL    := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi) ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc)
HOSTCC = cc
else
HOSTCC = gcc
endif
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTSTRIP = strip

  113 到 114行, 这是一个选项检查器,以确保我们只使用所支持的编译器,际上使用了一个shell函数,本函数使用了if-then语句,检测条件分别为"-S, -o, -xc",也用到了重定向

 cc-option = $(shell if $(CC) $(CFLAGS) $() -S -o /dev/null -xc /dev/null \
> /dev/null >&; then echo "$(1)"; else echo "$(2)"; fi ;)

  119 到 166 行,定义了交叉工具编译连,指定了交叉工具编译连的参数

 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
RANLIB = $(CROSS_COMPILE)RANLIB ifneq (,$(findstring s,$(MAKEFLAGS)))
ARFLAGS = cr
else
ARFLAGS = crv
endif
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -Os #-fomit-frame-pointer
ifndef LDSCRIPT
#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
ifeq ($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
else
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
endif
endif
OBJCFLAGS += --gap-fill=0xff gccincdir := $(shell $(CC) -print-file-name=include) CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
-D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \ ifneq ($(OBJTREE),$(SRCTREE))
CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include
endif CPPFLAGS += -I$(TOPDIR)/include
CPPFLAGS += -fno-builtin -ffreestanding -nostdinc \
-isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS) ifdef BUILD_TAG
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \
-DBUILD_TAG='"$(BUILD_TAG)"'
else
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
endif
  • #如果函数$(findstring s,$(MAKEFLAGS))不为空,也就是说能从$(MAKEFLAGS)中找到字符s,则定义AR选项为cr,否则为 crv
  • RELFLAGS、DBGFLAGS 和 OPTFLAGS 赋值
  • 如果没有定义链接脚本(LDSCRIPT),则指定链接脚本
  • 下面的都是编译的一些标志了,不具体分析了

  227 到 244 行,则是指定编译依赖

 ifndef REMOTE_BUILD

 %.s:    %.S
$(CPP) $(AFLAGS) -o $@ $<
%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $< else $(obj)%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
$(obj)%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
$(obj)%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
endif

  例如

  %.s: %.S

    $(CPP) $(AFLAGS) -o $@ $<

  %.s 依赖于 %.S

    -o  后面的为 $@ 为 %.s,$< 为所有依赖

  

  

二、主目录 Makefile 分析(2)的更多相关文章

  1. 二、主目录 Makefile 分析(3)

    2.8 编译选项 重新回到 主 makefile 中执行 2.8.1 u-boot  的编译顺序 代码166 到 189 行,这些是 u-boot 文件编译的顺序,由代码可以看到,首先是从cpu/$( ...

  2. 二、主目录 Makefile 分析(1)

    2.1 uboot 版本号 uboot 的版本号分三个级别: VERSION:主版本号 PATCHLEVEL:次版本号,为补丁级别 SUBLEVEL:再次版本号 EXTRAVERSION:附加版本信息 ...

  3. LibOpenCM3(二) 项目模板 Makefile分析

    目录 LibOpenCM3(一) Linux下命令行开发环境配置 LibOpenCM3(二) 项目模板 Makefile分析 LibOpenCM3 项目模板 项目模板地址: https://githu ...

  4. Android发展的一个重要方面Makefile分析

    Android发展的一个重要方面Makefile分析 随着移动互联网的发展,移动开发也越来越吃香了.眼下最火的莫过于android.android是什么就不用说了,android自从开源以来,就受到非 ...

  5. uboot 主Makefile分析

    一. Makefile 配置 1.1. make xxx_config 1.1.1. 笔者实验时是make x210_sd_config a. x210_sd_config是Makefile下的一个目 ...

  6. makefile 分析 -- 内置变量及自动变量

    makefile 分析1  -p 选项,可以打印出make过程中的数据库, 下面研究一下内置的变量和规则. -n 选项, 只运行,不执行, -d 选项,相当于--debug=a,  b(basic), ...

  7. uboot主Makefile分析(t配置和编译过程详解)

    1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_c ...

  8. uboot主Makefile分析

    VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(S ...

  9. (二)u-boot2013.01.01 for TQ210:《Makefile分析》

           当时写的时候看的是2012-10版本的,但是略对比了一遍和2013.01.01没什么改动,所以这不影响对2013.01.01版本的makefile的理解.本文比较侧重于语法句意的分析,框 ...

随机推荐

  1. CSS 选择器继承和层叠

    CSS选择器及其继承特性.层叠特性1.基本选择器  标记  id  class  这个就不再作介绍了 2.复合选择器  交集 交集选择器由两个选择器直接连接构成,其结果是选中二者各自元素范围的交集 其 ...

  2. Angular $cookieStore简单应用

    angular.module('cookieStoreExample', ['ngCookies']) .controller('ExampleController', ['$cookieStore' ...

  3. zabbix2.2 - FromDual.MySQL.check" became not supported

    升级zabbix后发现zabbix server日志中多个实例报错如下: 27974:20171227:113001.724 item "实例name:FromDual.MySQL.chec ...

  4. Bootstrap面板

    前面的话 面板(Panels)是Bootstrap框架新增的一个组件,某些时候可能需要将某些 DOM 内容放到一个盒子里.对于这种情况,可以使用面板组件.本文将详细介绍Bootstrap面板 基础面板 ...

  5. 最短路径——SPFA算法

    一.前提引入 我们学过了Bellman-Ford算法,现在又要提出这个SPFA算法,为什么呢? 考虑一个随机图(点和边随机生成),除了已确定最短路的顶点与尚未确定最短路的顶点之间的边,其它的边所做的都 ...

  6. MVC WebApi 图片上传和显示

    1 MVC中显示 内存流 中的图片.(不是图片文件) 创建一个Index用来显示 Action: public ActionResult Index() { return View(); } csht ...

  7. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)A,B,C

    A:链接:http://codeforces.com/contest/831/problem/A 解题思路: 从前往后分别统计递增,相等,递减序列的长度,如果最后长度和原序列长度相等那么就输出yes: ...

  8. JavaScript 隐式类型转换

    JavaScript 隐式类型转换 原文:https://blog.csdn.net/itcast_cn/article/details/82887895 · 1.1 隐式转换介绍 · 1.2 隐式转 ...

  9. android studio+grade配置构建

    Android 构建系统编译应用资源和源代码,然后将它们打包成可供您测试.部署.签署和分发的 APK.android Studio 使用 Gradle 这一高级构建工具包来自动化执行和管理构建流程,同 ...

  10. Leetcode 371.两整数之和 By Python

    不使用运算符 + 和 - ,计算两整数 a .b 之和. 示例 1: 输入: a = 1, b = 2 输出: 3 示例 2: 输入: a = -2, b = 3 输出: 1 思路 比如\(5+6=1 ...