config.mk 文件詳細分析
網友有這么一種說法
“u-boot根目錄下自帶一個config.mk文件,應 該說這才是真正的Makefile,以上介紹的兩個腳本Makefile和mkconfig完成了環境配置之后,在該文件中才定義具體的編譯規則,所以你會發現在各個子模塊(board、 cpu、lib_xxx、net、disk...)目錄中的Makefile第一句就是:include $(TOPDIR)/config.mk。”
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
#########################################################################
ifneq ($(OBJTREE),$(SRCTREE)) #如果目標存放目錄不等於源碼目錄(UBOOT頂層目錄)
ifeq ($(CURDIR),$(SRCTREE)) #如果當前目錄等於源碼目錄(UBOOT頂層目錄)
dir := #那么我們讓dir為空
else #否則
dir := $(subst $(SRCTREE)/,,$(CURDIR)) #把$(CURDIR)中的$(SRCTREE)/替換稱空,然后賦給dir
#例如:當前目錄如果為/u-boot-1.1.6/include/(源碼目錄為/u-boot-1.1.6/),
#則把/u-boot-1.1.6/include/中的/u-boot-1.1.6/替換為空,成為/include/
#例如:當前目錄如果為/u-boot-1.1.6/include/(源碼目錄為/u-boot-1.1.6/),
#則把/u-boot-1.1.6/include/中的/u-boot-1.1.6/替換為空,成為/include/
endif
obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/) #如果dir不為空,則把$(OBJTREE)/$(dir)/賦給obj,否則把直接把$(OBJTREE)/賦給obj
src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/) #如果src不為空,則把$(SRCTREE)/$(dir)/賦給src,否則把$(SRCTREE)/賦給src
$(shell mkdir -p $(obj)) # 通過一個shell函數創建obj路徑
else # 注意,這里的else對應上面的ifneq,這個else意思是目標存放目錄就等於uboot頂層目錄的時候,執行下面兩行
obj := #obj為空
src :=
endif
# clean the slate ... #清除三個不同的標記,下面會用到
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =
#
# When cross-compiling on NetBSD, we have to define __PPC__ or else we #當我們在NetBSD上進行交叉編譯的時候,我們得定義__PPC__
# will pick up a va_list declaration that is incompatible with the #否則我們得做一個 va_list 聲明,這個聲明是和實際的參數
# actual argument lists emitted by the compiler. #列表(由編譯器定義的參數列表)不兼容的。
#
# [Tested on NetBSD/i386 1.5 + cross-powerpc-netbsd-1.3]
ifeq ($(ARCH),ppc)
ifeq ($(CROSS_COMPILE),powerpc-netbsd-)
PLATFORM_CPPFLAGS+= -D__PPC__
endif
ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
PLATFORM_CPPFLAGS+= -D__PPC__
endif
endif
ifeq ($(ARCH),arm)
ifeq ($(CROSS_COMPILE),powerpc-netbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
endif
ifeq ($(ARCH),blackfin)
PLATFORM_CPPFLAGS+= -D__BLACKFIN__ -mno-underscore
endif
ifdef ARCH #指定預編譯體系結構選項
sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules
# 包含體系結構依賴規則,$(TOPDIR)/$(ARCH)_config.mk 即/u-boot-1.1.6/arm920t_config.mk
endif
#如果您希望對不存在且不能重新創建的makefile文件進行忽略,並且不產生錯誤信息,則使用-include指令代替include指令,格式如下:
#-include filenames...
#這種指令的作用就是對於任何不存在的makefile文件都不會產生錯誤(即使警告信息也不會產生)。如果希望保持和其它版本的make兼容,
#使用sinclude指令代替-include指令。
ifdef CPU #定義編譯時對齊,浮點等選項
sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules
# 包含特定的CPU的依賴規則, 即/u-boot-1.1.6/cpu/arm920t/config.mk
endif
ifdef SOC #$(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk 這個文件確實不存在,$(TOPDIR)/cpu/$(CPU)/目錄下倒是有一個config.mk
sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk # include SoC specific rules #包含特定的片上系統的依賴規則
endif
ifdef VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif
ifdef BOARD
#對各個目標文件進行鏈接時的內存基地址(定義在/u-boot-1.1.6/board/smdk2410/config.mk)TEXT_BASE = 0x33F80000,相當重要!!!!
#這里可以參考一篇文章,這篇文章對uboot內存分配做了比較詳細的解釋。點擊連接:
#http://zqwt.012.blog.163.com/blog/static/120446842010323113546103/
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif
#########################################################################
CONFIG_SHELL := $(shell if [ -x "
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi)
##################################################################################################################
# 這里把test命令好好整一下:
# 用途:評估條件表達式。
# 語法:test Expression 或 [ Expression ]
# 描述:test 命令用於評估 Expression 參數, 如果表達式值為 True,返回一個零(true)退出值。
# 否則, test 命令返回一個非零(false)退出值。 如果沒有參數,test 命令也返回一個非零退出值。
#注: 1、在命令的第二種格式中,[ ](方括號)必須被空白包圍。
# 2、必須在 C shell 中對文件名進行顯式測試。文件名替換(全局)會導致 shell 腳本退出。
# Expression 參數指的是一個需要被檢查為 true 或 false 的條件的語句。下列函數可用來構造此參數:
# -x FileName 意思是如果所指定的FileName存在且可執行,則返回一個 true 退出值。
# 如果所指定的文件存在且是一個目錄,true 退出值表示當前進程被允許在目錄中搜索。
##################################################################################################################
ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc)
HOSTCC = cc
else
HOSTCC = gcc
endif
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTSTRIP = strip
#########################################################################
#
# Option checker (courtesy linux kernel) to ensure
# only supported compiler options are used
#
# 這是一個選項檢查器,以確保我們只使用所支持的編譯器
#
# 這一句實際上使用了一個shell函數,本函數使用了if-then語句,檢測條件分別為"-S, -o, -xc",也用到了重定向,具體含義可以自己分析
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
#
# 這是這個腳本所做的第一件事:定義交叉編譯鏈工具
# Include the make variables (CC, etc...)
# 這里$(CROSS_COMPILE)即你的交叉編譯器安裝目錄
#
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
# 這是這個腳本所做的第二件事:定義AR、調試、優化、預處理、C編譯器、鏈接選項
ifneq (,$(findstring s,$(MAKEFLAGS))) #如果函數$(findstring s,$(MAKEFLAGS))不為空,也就是說能從$(MAKEFLAGS)中找到字符s
ARFLAGS = cr #則定義AR選項
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),即/u-boot-1.1.6/board/smdk2410/u-boot.lds,這個文件定義了鏈接時,各個目標文件是如何組織的
#可以參閱:http://zqwt.012.blog.163.com/blog/static/120446842010320101137932/
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
# avoid trigraph warnings while parsing pci.h (produced by NIOS gcc-2.9)
# this option have to be placed behind -Wall -- that's why it is here
ifeq ($(ARCH),nios)
ifeq ($(findstring 2.9,$(shell $(CC) --version)),2.9)
CFLAGS := $(CPPFLAGS) -Wall -Wno-trigraphs
endif
endif
# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>
# option to the assembler.
AFLAGS_DEBUG :=
# turn jbsr into jsr for m68k
ifeq ($(ARCH),m68k)
ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4)
AFLAGS_DEBUG := -Wa,-gstabs,-S
endif
endif
AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)
LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS) #定義鏈接選項
#指定了起始地址TEXT_BASE
# Location of a usable BFD library, where we define "usable" as #BFD庫的定位器,在此我們定義所謂的
# "built for ${HOST}, supports ${TARGET}". Sensible values are #"usable"為"built for ${HOST}, supports ${TARGET}".敏感的值
# - When cross-compiling: the root of the cross-environment #是當交叉編譯的時候:交叉環境變量的root
# - Linux/ppc (native): /usr
# - NetBSD/ppc (native): you lose ... (must extract these from the
# binutils build directory, plus the native and U-Boot include
# files don't like each other)
#
# So far, this is used only by tools/gdb/Makefile. #至今,這僅僅被tools/gdb/Makefile使用
ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc) #如果主機操作系統和硬件體系結構為darwin-ppc
BFD_ROOT_DIR = /usr/local/tools #那么.............
else
ifeq ($(HOSTARCH),$(ARCH)) #如果主機體系結構為arm920t
# native
BFD_ROOT_DIR = /usr #那么BFD_ROOT_DIR = /usr
else #否則
#BFD_ROOT_DIR = /LinuxPPC/CDK # Linux/i386
#BFD_ROOT_DIR = /usr/pkg/cross # NetBSD/i386
BFD_ROOT_DIR = /opt/powerpc
endif
endif
ifeq ($(PCI_CLOCK),PCI_66M)
CFLAGS := $(CFLAGS) -DPCI_66M
endif
#########################################################################
export CONFIG_SHELL HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE \
AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP \
MAKE
export TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
#########################################################################
#這是此腳本要做的第三件事情:指定編譯規則
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
#########################################################################