自己动手写一个Makefile

  目标硬件:STM32F103RB(ARM Cortex M3架构)

     项目中需要把程序从armcc转移到gcc下,自然需要编写makefile文件,由于以前没怎么接触过,项目中的文件又很多,所以先简单的创建几个源文件试验一把。

需求:

    1.源文件目录makefile目录不同   
    2.生成中间文件*.o等放入指定目录./obj  
    3.生成目标.elf,.bin文件放入指定目录./bin中

准备工作:

    1.准备源文件:从cmsis下找了一个stm32的启动代码gcc版,随便写了个main.c,header.h),和一个已经写好的链接脚本stm32f10x.ld(关于链接脚本以后再介绍,网上相关资料也不少)。 
    2.gcc工具链:http://www.codesourcery.com/sgpp/lite/arm 下载安装
    3.参考at91lib中的makefile

开始:

    1.User-modifiable options,需要指定的部分
   
CHIP = STM32F103RB

# Optimization level, put in comment for debugging
OPTIMIZATION = -Os

# Special the link script file
LDS := stm32f10x.ld

# app directory
APP_DIR :=  app
# 还可以接着添加其他目录

# Output file basename
OUTPUT := $(CHIP)-Flash
# 生成目标文件名

# Output directories
BIN_DIR := bin
OBJ_DIR := obj
   
    2.Tools,指定gcc工具链
CROSS_COMPILE := arm-none-eabi-

# Compilation tools
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
RM    := rm -rf  
MKDIR := mkdir -p

# includes
# example: INCLUDES += -I$(AT91LIB)
INCLUDES  =

# defines
# 预定义,默认为1
# example: DEFINES += -D$(CHIP)
DEFINES =

TARGET_OPTS = -mcpu=cortex-m3 -mthumb
       
CFLAGS = $(TARGET_OPTS)
CFLAGS += -Wall -mlong-calls -ffunction-sections
CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) $(DEFINES)
ASFLAGS = $(TARGET_OPTS) -Wall -g $(OPTIMIZATION) $(INCLUDES) $(DEFINES) -D__ASSEMBLY__
LDFLAGS = $(OPTIMIZATION) -nostartfiles $(TARGET_OPTS) -Wl,-Map=$(OUTPUT).map,--cref,--gc-sections
       
    3.Files,指定要编译的源文件

# Directories where source files can be found
# make会从VPATH找到源文件,如果我们要用源文件,也不需要再指定其目录
VPATH += $(APP_DIR)

# Objects built from C source files

APP_SRCS  := $(wildcard $(APP_DIR)/*.c)                 # result: APP_SRCS = app/startup_stm32f10x.c app/main.c
APP_SRCS  := $(subst $(APP_DIR)/,, $(APP_SRCS)) # result: APP_SRCS = startup_stm32f10x.c main.c

SRCS := $(APP_SRCS)                                               #result: SRCS = startup_stm32f10x.c main.c


C_OBJECTS := $(patsubst %.c,%.o,$(SRCS))           #result: C_OBJECTS = startup_stm32f10x.o main.o

# Append OBJ and BIN directories to output filename
OUTPUT := $(BIN_DIR)/$(OUTPUT)                           #result: OUTPUT = bin/STM32F103RB-Flash
       
    4.Rules,依赖关系
TARGET_BIN :=  $(OUTPUT).bin                                #目录elf文件名
TARGET_ELF :=  $(OUTPUT).elf                                 #目录bin文件名
C_OBJECTS_EXT := $(addprefix $(OBJ_DIR)/, $(C_OBJECTS))    #result: C_OBJECTS = obj/startup_stm32f10x.o obj/main.o
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJECTS_EXT))       #result: C_DEPS_EXT = obj/startup_stm32f10x.d obj/main.d

#目标文件集:依赖目标集   
all:  $(OBJ_DIR) $(BIN_DIR) $(TARGET_BIN)            # all 依赖$(OBJ_DIR) $(BIN_DIR) $(TARGET_BIN)
$(BIN_DIR):
    mkdir -p $@
$(OBJ_DIR):
    mkdir -p $@

$(TARGET_BIN): $(TARGET_ELF)                              # bin文件依赖elf文件
#Usage: arm-none-eabi-objcopy [option(s)] in-file [out-file]
# $< 依赖目标中的第一个名字
# $@ 目标文件集
# tab键开始命令
    $(OBJCOPY) -O binary $< $@


$(TARGET_ELF) : $(C_OBJECTS_EXT)                      # elf文件依赖所有.o文件
# $^所有依赖目标的集合
# -T$(LDS)指定链接脚本
    $(CC) $(LDFLAGS) -T$(LDS) -o $@ $^

$(C_OBJECTS_EXT) : $(SRCS)                                 # 可删了
$(OBJ_DIR)/%.d : %.c                                             # 自动生成依赖关系,使用gcc -MM参数,例如:main.d内容为 obj/main.o: app/main.c app/header.h
#-MT指定target 如obj/main.o,不加此选项默认为main.o
# $<依赖目标中的第一个名字,此处不能使用$@
# >管道输出到目标文件
    $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@

$(OBJ_DIR)/%.o :%.c
$(CC) $(CFLAGS) -c $< -o $@

#包含生成的.d文件,自动生成依赖关系
#比如:obj/main.o: app/main.c app/header.h,当我们修改header.h后,会更新main.o
#如果仅有%.o : %.c,则如果.h更改后,不会更新对应的.o
-include $(C_DEPS_EXT)

5.总结:
    弄懂依赖关系最重要,bin->elf->%.o->%.c
    几个常用的自动化变量搞懂:$@,$^,$<
    gcc工具链的使用要知道
    套用现在的makefile
   
ps:(第一次在CSDN上写blog,不足之处,多多见谅)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值