目标硬件: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,不足之处,多多见谅)
自己动手写一个Makefile
最新推荐文章于 2023-02-11 15:08:13 发布