Makefile 管理

本文介绍了使用Makefile管理嵌入式开发工程的方法,通过定义变量和规则,实现自动化编译流程,减少重复劳动并提高效率。通过一个具体的示例,展示了如何生成通用的Makefile,覆盖不同类型的源文件和编译选项。

 Makefile百科简介:一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

     在进行工程管理时往因为编译工具或源文件类型,数目多少等等的原因,需得重复编写代码

那如何生成一个通用的Makefile呢? 如下例:

 

# CORTEX-A9 PERI DRIVER CODE
# VERSION 2.0
# ATHUOR Je_Cortex
# MODIFY DATE
# 2014.05.28  Makefile

CROSS_COMPILE = arm-none-eabi-
#定义一个变量,CROSS_COMPILE ,变量值arm-none-eabi- 
#交叉编译工具的前缀

NAME =led
#定义一个变量NAME,变量值 led
#生成的文件名称

#================================================================#
CFLAGS += -g   -O0  -mabi=apcs-gnu -mfpu=neon -mfloat-abi=softfp  -fno-builtin \
    -nostdinc  -I ./common/include      #告诉编译器不链接gnu 内建库,链接当前路径下的./common/include
# += 变量的原值后面追加
# CFLAGS 是makefile的默认变量,作为gcc的选项
# 对变量CFLAGS,追加值
#  -E  -S  -c  -o  -g   -D  -i   -I  -l  -L
                                          
LD = $(CROSS_COMPILE)ld
#定义一个变量 LD =arm-none-eabi-ld
 
CC = $(CROSS_COMPILE)gcc
#定义一个变量 CC =arm-none-eabi-gcc

OBJCOPY = $(CROSS_COMPILE)objcopy
#定义一个变量 OBJCOPY =arm-none-eabi-objcopy

OBJDUMP = $(CROSS_COMPILE)objdump
##定义一个变量 OBJDUMP =arm-none-eabi-objdump


#================================================================#
OBJSss  := $(wildcard start/*.S) $(wildcard common/src/*.S) $(wildcard *.S)\
     $(wildcard start/*.c) $(wildcard common/src/*.c)       \
     $(wildcard usr/*.c) $(wildcard *.c) 

#$(wildcard start/*.S) : 按指定内容(start目录下,所有以.S结尾的指令)进行文件搜索,返回搜到的文件名


OBJSs   := $(patsubst %.S,%.o,$(OBJSss))
#定义变量OBJSs,变量的值为:start.o   _udivsi3.o   _umodsi3.o   uart.c  printf.c  led.c
#$(patsubst %.S,%.o,$(OBJSss))  按照指定的规则(对变量OBJSss的值.S 替换成.o)对字符内容进行替换

OBJS  := $(patsubst %.c,%.o,$(OBJSs))
#定义变量OBJS,变量的值为:start.o   _udivsi3.o   _umodsi3.o   uart.o  printf.o  led.o
#================================================================#
%.o: %.S 
 $(CC) $(CFLAGS) -c -o  $@ $<
%.o: %.c
 $(CC) $(CFLAGS) -c -o  $@ $<


all:clean  $(OBJS)
 $(LD)  $(OBJS) -T map.lds -o $(NAME).elf
 $(OBJCOPY)  -O binary  $(NAME).elf $(NAME).bin 
 $(OBJDUMP) -D $(NAME).elf > $(NAME).dis

#all:clean $(OBJS) 清除所有.o文件,防止修改.h后不编译
#$(LD)  $(OBJS) -T map.lds -o $(NAME).elf
# arm-none-eabi-ld  start.o  _udivsi3.o   _umodsi3.o   uart.o  printf.o  led.o  -T map.lds -o led.elf
#根据链接脚本,链接生成elf

#$(OBJCOPY)  -O binary  $(NAME).elf $(NAME).bin
# arm-none-eabi-objcopy -O binary  led.elf  led.bin  二进制格式转换

#$(OBJDUMP) -D $(NAME).elf > $(NAME).dis 
# arm-none-eabi-objdump -D led.elf >  led.dis
#=================================================================#
clean:
 rm -rf $(OBJS) *.elf *.bin *.dis *.o
#=====================================

由于给定引用未提及头歌平台相关内容,下面基于Makefile通用知识给出在头歌平台实践中使用Makefile的方法和经验。 ### 使用方法 - **基本规则编写**:Makefile核心是规则,规则格式为目标: 依赖,然后换行以Tab键开头编写命令。例如,要编译一个C程序`main.c`生成可执行文件`main`,Makefile可写成: ```makefile main: main.c gcc -o main main.c ``` - **多文件编译**:对于多个源文件,可分别列出依赖关系。如存在`main.c`、`func1.c`和`func1.h`,Makefile可写成: ```makefile main: main.o func1.o gcc -o main main.o func1.o main.o: main.c func1.h gcc -c main.c func1.o: func1.c func1.h gcc -c func1.c ``` - **变量使用**:使用变量可提高Makefile的可维护性。例如: ```makefile CC = gcc CFLAGS = -Wall -g main: main.o func1.o $(CC) $(CFLAGS) -o main main.o func1.o main.o: main.c func1.h $(CC) $(CFLAGS) -c main.c func1.o: func1.c func1.h $(CC) $(CFLAGS) -c func1.c ``` - **隐含规则利用**:Make默认有很多隐含规则。如上述例子中,编译`.o`文件的规则可省略,因为Make有默认的编译C文件生成目标文件的隐含规则。 ```makefile CC = gcc CFLAGS = -Wall -g main: main.o func1.o $(CC) $(CFLAGS) -o main main.o func1.o ``` ### 相关经验 - **模块化管理**:在大工程中,将不同模块或功能的源文件放在不同目录,每个目录编写独立Makefile,总控Makefile调用各子目录Makefile,可使Makefile更简洁,便于维护和模块、分段编译 [^2]。 - **变量灵活运用**:利用变量定义编译器、编译选项等,可方便修改编译参数。还能在make命令行传入变量值或在环境变量中设置,也能使用`-R`或`--no– builtin-variables`参数取消变量对隐含规则的作用 [^4]。 - **检查目录结构**:Makefile编写要配合工程目录结构,否则即使Makefile语法正确,编译也可能出错。编写时要确保目录路径正确 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值