uboot的编译选项差不多都写在顶层的config.mk中。下面分析此文件中和编译选项有关的部分。
定义本地编译环境变量:
-
ifeq ($(HOSTOS),darwin) #如果主机系统为darwin则主机编译器为cc否则为gcc
-
HOSTCC = cc
-
else
-
HOSTCC = gcc
-
endif
-
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
-
HOSTSTRIP = strip
HOSTCFLAGS变量保存选项:
-Wall : 显示编译中的警告信息
-Wstrict-prototypes : 如果函数的声明或定义没有指出参数类型,编译器就发出警告.
-O2 : 使用O2级别的优化
-fomit-frame-pointer : 对于不需要帧指针的函数,不要在寄存器中保存帧指针
下面有一个cc-option变量,此变量保存了一个测试编译选项的命令。其他地方会经常用call函数来调用它,测试编译选项。
-
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 ;)
这条语句写整齐了如下:
-
if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1;then
-
echo "$(1)";
-
else
-
echo "$(2)";
-
fi;
可以看出这是一条编译命令,变量CC是编译器,变量CFLAGS是编译选项,其中选项
-S:编译后立即结束,不进行汇编等操作。
-o /dev/null : 生成文件到/dev/null,即不生成任何编译结果,要编译的文件也为空。
-xc: 指定按c语言编译
调用此语句如:call cc-option,-a,-b 则如果支持-a选项则返回-a否则返回-b。
下面变量是定义各个编译用到的工具,CROSS_COMPILE在顶层Makefile中定义
-
AS = $(CROSS_COMPILE)as #汇编器
-
LD = $(CROSS_COMPILE)ld #连接器
-
CC = $(CROSS_COMPILE)gcc #编译器
-
CPP = $(CC) -E #预处理
-
AR = $(CROSS_COMPILE)ar #归档文件
-
NM = $(CROSS_COMPILE)nm #列出object文件中的符号
-
LDR = $(CROSS_COMPILE)ldr #
-
STRIP = $(CROSS_COMPILE)strip #丢弃目标文件中的符号
-
OBJCOPY = $(CROSS_COMPILE)objcopy #转换目标文件格式
-
OBJDUMP = $(CROSS_COMPILE)objdump #反汇编
-
RANLIB = $(CROSS_COMPILE)RANLIB #产生归档文件索引
接下来和编译选项有关的是
-
ifdef ARCH
-
sinclude $(TOPDIR)/lib_$(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
这几行包含了和ARCH,CPU,SOC,BOARD等相关的编译选项的config.mk文件,以lib_arm/config.mk文件为例,此文件中包含这么一句:
-
PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
-D选项是定义的意思,此句即为定义CONFIG_ARM __ARM__这两个值,如果编译C文件则相当于#define CONFIG_ARM这样的语句
还有如下语句:
-
PLATFORM_CPPFLAGS += $(call cc-option,-marm,)
根
据前面提到的cc-option的分析,可以看出,此句测试-marm选项如果被支持的添加进PLATFORM_CPPFLAGS变量,否则则添加空值。
后面call函数调用的都是测试一些选择是否能被支持如果支持就添加。此文件中都是尝试添加一切arm体系相关的选项。
此文件最后指定了lds连接文件
-
LDSCRIPT := $(SRCTREE)/cpu/$(CPU)/u-boot.lds
其他config.mk文件类似。
BOARD相关目录中的config.mk,本例mini2440目录中config.mk则只定义了TEXT_BASE = 0x33F80000,这个变量保存了uboot在内存中运行地址。
顶层config.mk中接下来是整合这些编译选项,整理下大致如下,
-
RELFLAGS= $(PLATFORM_RELFLAGS)
-
DBGFLAGS= -g # -DDEBUG #-g 添加调试信息
-
OPTFLAGS= -Os #-fomit-frame-pointer
-
OBJCFLAGS += --gap-fill=0xff #段之间的空隙用0xff填充
-
gccincdir := $(shell $(CC) -print-file-name=include) #编译器的include路径
-
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) -D__KERNEL__
-
#此变量综合了DBGFLAGS,OPTFLAGS,RELFLAGS编译选项,并定义了__KERBEL__
-
-
ifneq ($(TEXT_BASE),)
-
CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) #定义了TEXT_BASE变量
-
endif
-
CPPFLAGS += -I$(TOPDIR)/include #添加include搜索路径
-
CPPFLAGS += -fno-builtin -ffreestanding -nostdinc \
-
-isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)
-
#-fno-builtin 不接受不是两个下划线的内建函数
-
#-ffreestanding 安独立环境编译
-
#-nostdinc 不要在标准系统目录中寻找头文件 只在-I指定的目录中搜索
-
#-isystem 指定系统目录
-
#-pipe 在编译的不同阶段使用管道通讯
-
#$(PLATFORM_CPPFLAGS) 添加
-
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
-
#-Wstrict-prototypes如果函数的声明或定义没有给出参数类型则警告
-
CFLAGS += $(call cc-option,-fno-stack-protector)
-
#尝试添加-fno-stack-protector选项
-
AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)
-
LDFLAGS += -Bstatic -T $(obj)u-boot.lds $(PLATFORM_LDFLAGS)
-
#-Bstatic静态编译 使用u-boot.lds连接描述文件,此文件是LDSCRIPT变量保存的路径复制过来的
-
ifneq ($(TEXT_BASE),)
-
LDFLAGS += -Ttext $(TEXT_BASE) #连接运行时的内存地址
-
endif
下面几行规定了各种文件的编译时用到的编译选项:
BCURDIR := $(notdir $(CURDIR))
-
$(obj)%.s: %.S
-
$(CPP) $(AFLAGS) $(AFLAGS_$(@F)) $(AFLAGS_$(BCURDIR)) -o $@ $<
-
$(obj)%.o: %.S
-
$(CC) $(AFLAGS) $(AFLAGS_$(@F)) $(AFLAGS_$(BCURDIR)) -o $@ $< -c
-
$(obj)%.o: %.c
-
$(CC) $(CFLAGS) $(CFLAGS_$(@F)) $(CFLAGS_$(BCURDIR)) -o $@ $< -c
-
$(obj)%.i: %.c
-
$(CPP) $(CFLAGS) $(CFLAGS_$(@F)) $(CFLAGS_$(BCURDIR)) -o $@ $< -c
-
$(obj)%.s: %.c
-
$(CC) $(CFLAGS) $(CFLAGS_$(@F)) $(CFLAGS_$(BCURDIR)) -o $@ $< -c -S
从上面代码可以设置
文件夹级编译选项$(CFLAGS_$(BCURDIR)):
如果想改变drivers/mtd/nand/所有文件编译选项
可以修改nand/Makefile
CFLAGS_nand += -g -O0
文件级编译选项$(CFLAGS_$(@F)): #@F 去掉目标文件的文件夹,只留下文件名
这里以/cpu/arm920t/at91rm9200/dm9161.c 举例
CFLAGS_dm9161.o += -O0 -g
include $(TOPDIR)/config.mk
CFLAGS_at91rm9200 += -g -O0
编译信息:
/usr/local/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-eabi-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ -DTEXT_BASE=0x21f00000 -I/home/enzo/H9200F/u-boot-2009.08/include -fno-builtin -ffreestanding -nostdinc -isystem /usr/local/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/arm-none-eabi/4.5.2/include -pipe -DCONFIG_ARM -D__ARM__ -marm -mabi=aapcs-linux -mno-thumb-interwork -march=armv4 -Wall -Wstrict-prototypes -fno-stack-protector -O0 -g -g -O0 -o dm9161.o dm9161.c -c
可以看出 -O0 -g 选项被使用
阅读(1357) | 评论(0) | 转发(0) |