简单的裸机makefile工程

来源:互联网 发布:管家婆数据库搬移工具 编辑:程序博客网 时间:2024/04/19 12:29

makefile工程的基本思想:
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运行,注意:每次下载裸机程序都要复位
/*****************************************************/

driver目录下的makefile:
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    
/******************************************/














0 0
原创粉丝点击