• 二、主目录 Makefile 分析(2)


    2.7 编译选项---config.mk

      代码 163 164 行

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

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

    2.7.1 topdir/config.mk 分析

      代码 26 到 45行:

     1 ifneq ($(OBJTREE),$(SRCTREE))
     2 ifeq ($(CURDIR),$(SRCTREE))
     3 dir :=
     4 else
     5 dir := $(subst $(SRCTREE)/,,$(CURDIR))
     6 endif
     7 
     8 obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)
     9 src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/)
    10 
    11 $(shell mkdir -p $(obj))
    12 else
    13 obj :=
    14 src :=
    15 endif
    16 
    17 # clean the slate ...
    18 PLATFORM_RELFLAGS =
    19 PLATFORM_CPPFLAGS =
    20 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 不能匹配,不会执行

    1 ifeq ($(ARCH),arm)
    2 ifeq ($(CROSS_COMPILE),powerpc-netbsd-)
    3 PLATFORM_CPPFLAGS+= -D__ARM__
    4 endif
    5 ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
    6 PLATFORM_CPPFLAGS+= -D__ARM__
    7 endif
    8 endif

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

     1 ifdef    ARCH
     2 sinclude $(TOPDIR)/$(ARCH)_config.mk    # include architecture dependend rules
     3 endif
     4 ifdef    CPU
     5 sinclude $(TOPDIR)/cpu/$(CPU)/config.mk    # include  CPU    specific rules
     6 endif
     7 ifdef    SOC
     8 sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk    # include  SoC    specific rules
     9 endif
    10 ifdef    VENDOR
    11 BOARDDIR = $(VENDOR)/$(BOARD)
    12 else
    13 BOARDDIR = $(BOARD)
    14 endif
    15 ifdef    BOARD
    16 sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk    # include board specific rules
    17 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" 的形式输出所有参数。
     1 CONFIG_SHELL    := $(shell if [ -x "$$BASH" ]; then echo $$BASH; 
     2             else if [ -x /bin/bash ]; then echo /bin/bash; 
     3             else echo sh; fi ; fi)
     4 
     5 ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc)
     6 HOSTCC        = cc
     7 else
     8 HOSTCC        = gcc
     9 endif
    10 HOSTCFLAGS    = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
    11 HOSTSTRIP    = strip

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

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

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

     1 AS    = $(CROSS_COMPILE)as
     2 LD    = $(CROSS_COMPILE)ld
     3 CC    = $(CROSS_COMPILE)gcc
     4 CPP    = $(CC) -E
     5 AR    = $(CROSS_COMPILE)ar
     6 NM    = $(CROSS_COMPILE)nm
     7 STRIP    = $(CROSS_COMPILE)strip
     8 OBJCOPY = $(CROSS_COMPILE)objcopy
     9 OBJDUMP = $(CROSS_COMPILE)objdump
    10 RANLIB    = $(CROSS_COMPILE)RANLIB
    11 
    12 ifneq (,$(findstring s,$(MAKEFLAGS)))
    13 ARFLAGS = cr
    14 else
    15 ARFLAGS = crv
    16 endif
    17 RELFLAGS= $(PLATFORM_RELFLAGS)
    18 DBGFLAGS= -g # -DDEBUG
    19 OPTFLAGS= -Os #-fomit-frame-pointer
    20 ifndef LDSCRIPT
    21 #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
    22 ifeq ($(CONFIG_NAND_U_BOOT),y)
    23 LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
    24 else
    25 LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
    26 endif
    27 endif
    28 OBJCFLAGS += --gap-fill=0xff
    29 
    30 gccincdir := $(shell $(CC) -print-file-name=include)
    31 
    32 CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)        
    33     -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE)        
    34 
    35 ifneq ($(OBJTREE),$(SRCTREE))
    36 CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include
    37 endif
    38 
    39 CPPFLAGS += -I$(TOPDIR)/include
    40 CPPFLAGS += -fno-builtin -ffreestanding -nostdinc     
    41     -isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)
    42 
    43 ifdef BUILD_TAG
    44 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes 
    45     -DBUILD_TAG='"$(BUILD_TAG)"'
    46 else
    47 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
    48 endif
    • #如果函数$(findstring s,$(MAKEFLAGS))不为空,也就是说能从$(MAKEFLAGS)中找到字符s,则定义AR选项为cr,否则为 crv
    • RELFLAGS、DBGFLAGS 和 OPTFLAGS 赋值
    • 如果没有定义链接脚本(LDSCRIPT),则指定链接脚本
    • 下面的都是编译的一些标志了,不具体分析了

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

     1 ifndef REMOTE_BUILD
     2 
     3 %.s:    %.S
     4     $(CPP) $(AFLAGS) -o $@ $<
     5 %.o:    %.S
     6     $(CC) $(AFLAGS) -c -o $@ $<
     7 %.o:    %.c
     8     $(CC) $(CFLAGS) -c -o $@ $<
     9 
    10 else
    11 
    12 $(obj)%.s:    %.S
    13     $(CPP) $(AFLAGS) -o $@ $<
    14 $(obj)%.o:    %.S
    15     $(CC) $(AFLAGS) -c -o $@ $<
    16 $(obj)%.o:    %.c
    17     $(CC) $(CFLAGS) -c -o $@ $<
    18 endif

      例如

      %.s: %.S

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

      %.s 依赖于 %.S

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

      

      

  • 相关阅读:
    【js效果】密码的显示和隐藏
    【js效果】竖向折叠二级菜单
    【js效果】单行文字滚动(从左到右)
    mysql:查询排名
    init_bootmem_node
    bootmem_init_node
    for_each_node(node)
    build_mem_type_table
    __vet_atags
    asm-offset.h 生成
  • 原文地址:https://www.cnblogs.com/kele-dad/p/8893709.html
Copyright © 2020-2023  润新知