1.把子目录下的所有的源文件都编成库(.so,.a,.o),多个.o合起来就叫库。
2.顶层makefile将子目录的所有库链接成可执行文件
3.顶层makefile要能不断递归调用子目录下的makefile进行源文件的编译
4.为了递归,所有我们要实现一个规则文件
//------------------------------------------
裸机工程管理文件:
各目录makefile
链接脚本app.lds
规则文件rules.mk或是rules.make
//--------------------------------------------
顶层makefile://编译时要输出各种信息(反汇编,符号,),以便于出错调试
/**********************************/
DRIVERS-y :=
DRIVERS-y += init/main_init.o//将init目录下的所有.o或是源文件变为一个名字为main_init.o的.o库
DRIVERS-y += drivers/uart/uart_driver.o//添加一个目录则只需要添加一个库,改一下规则文件即可
objs := $(DRIVERS-y)
TOPDIR := $(shell /bin/pwd)//
CROSSTOOLDIR := /usr/local/arm/4.3.2//交叉编译器路径
CROSS_COMPILE = $(CROSSTOOLDIR)/bin/arm-linux-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
NM = $(CROSS_COMPILE)nm
DIR_INCLUDE = -I$(TOPDIR)/include//
LFLAGS = -Tapp.lds -Bstatic//指定链接脚本,指定静态链接
CLIBSDIR = $(CROSSTOOLDIR)/arm-none-linux-gnueabi/libc/armv4t/usr/lib
GCCLIBSDIR = $(CROSSTOOLDIR)/lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t
ARMLIBS = -L$(CLIBSDIR) -lc -L$(GCCLIBSDIR) -lgcc
export CC LD OBJCOPY OBJDUMP DIR_INCLUDE TOPDIR
app.bin :subdirs $(objs)//subdirs依赖,在规则文件中实现
$(LD) -v $(LINKFLAGS) -o app_elf $(objs) $(ARMLIBS)//多个.o链接为一个文件
//生成elf格式文件(-v是查看链接过程)($(ARMLIBS)指定一小部分不依赖内核的标准c库)
$(OBJCOPY) -O binary -S app_elf $@
//去除elf格式生成 $@目标文件app.bin
$(OBJDUMP) -D -m arm app_elf > app.dis
//生成反汇编信息
$(NM) -v -l app_elf > app.map
//生成符号信息
clean:
find -name '*.o' | xargs rm -f
rm -f app.dis app.bin app_elf app.map
include Rules.make//Rules.make规则文件被所有的makefile包含,而顶层的makefile只需调用Rules.make中大写的MAKE
/*****************************************************/
通过串口或网线下载到开发板,然后go运行,注意:每次下载裸机程序都要复位
/*****************************************************/
O_TARGET := uart_driver.o
obj-y += uart.o//指定目标文件
include $(TOPDIR)/Rules.make//包含顶层目录下的规则文件
/**********************************/
init目录下的makefile:
O_TARGET := main_init.o//O_TARGET目标名称即.o库名称
//要实现目标库,就需要下面的依赖文件,通过包含Rules.make来建立依赖关系
obj-y :=
obj-y += main.o
//obj-y += add.o
//当需要往一个目录下添加一个文件时,只需要将文件放到目录下,然后改当前目录下的makefile,\
无需修改顶层makefile
include $(TOPDIR)/Rules.make
//导致的结果是.o库中由原来的一个文件变为了两个文件。由规则文件实现的
/***************************************/
规则文件:
unexport O_TARGET//unexport:不导出,只共当前目录使用
unexport obj-y
unexport subdirs
unexport SUBDIRS
ifdef O_TARGET//如果当前目录声明了O_TARGET,
$(O_TARGET): $(obj-y)//obj-y是一堆.o依赖文件,由下面%.o:%.c生成
rm -f $@//删除旧的库文件
$(LD) -r -o $@ $^//链接,生成.o
endif # O_TARGET
%.o:%.c
$(CC) -Wall -c -O2 -o $@ $< $(DIR_INCLUDE) -fno-builtin-printf
%.o:%.S
$(CC) -Wall -c -O2 -o $@ $< $(DIR_INCLUDE) -fno-builtin-printf
#子目录makefile的递归调用:当有新的目录时要在这里加上
SUBDIRS=init drivers/uart//添加新目录位置,
.PHONY:subdirs $(SUBDIRS)
subdirs:$(SUBDIRS)//subdirs是顶层makefile链接时的依赖,而SUBDIRS是subdirs依赖的两个目录
$(SUBDIRS)://循环取变量,因为变量是个目录,所以通过$(MAKE) -C init跳到init目录下make
$(MAKE) -C $@ //MAKE是makefile内部提供的可以递归调用子目录下面的makefile
/******************************************/