Makefile使用细节

###变量及通配符
这里写图片描述

A := $(C)	# 即时变量,此时C未定义,A为空
B = $(C)	# 延时变量,用到B时再确定具体的值
C = abc
C ?= 123	# C不是第一次定义,被忽略
C += 789
D ?= xyz	# D是第一次定义

all:
	@echo A = $(A)
	@echo B = $(B)
	@echo C = $(C)
	@echo D = $(D)

输出:

A =
B = abc 789
C = abc 789
D = xyz 

###函数
这里写图片描述

A = a b c
B = $(foreach v, $(A), $(v).c)	# 取出$(A)中的每一项存到v中,执行$(v).c,最后以空格分隔返回
C = $(B)
C += d.o
D = $(filter %.c, $(C))			# 返回$(C)中所有符合%.c的项
E = $(filter-out %.c, $(C))		# 返回$(C)中所有不符合%.c的项
files := $(wildcard *.c)		# 获取当前目录下所有的.c文件
files_obj := $(patsubst %.c, %.o, $(files))	# 将$(files)中所有符合%.c的项替换为%.o
files_obj2 := $(files:%.c=%.o)	# 效果和patsubat相同


func:
	@echo A = $(A)
	@echo B = $(B)
	@echo C = $(C)
	@echo D = $(D)
	@echo E = $(E)
	@echo files = $(files)
	@echo files_obj = $(files_obj)
	@echo files_obj2 = $(files_obj2)

输出:

A = a b c
B = a.c b.c c.c
C = a.c b.c c.c d.o
D = a.c b.c c.c
E = d.o
files = a.c test.c
files_obj = a.o test.o
files_obj2 = a.o test.o

###实例:

default:
	arm-linux-gcc -c start.s -o OBJ/start.o
	arm-linux-gcc -c LED/led.c -o OBJ/led.o
	arm-linux-gcc -c KEY/key.c -o OBJ/key.o
	arm-linux-gcc -c main.c -o OBJ/main.o
	arm-linux-ld -Ttext=0x42C00000 OBJ/start.o OBJ/led.o OBJ/key.o OBJ/main.o -o OBJ/main.elf
	arm-linux-objcopy -I elf32-littlearm -Obinary OBJ/main.elf main.bin

clean:
	rm *.bin OBJ/*.o OBJ/*.elf

上面是一般的写法;
下面是优雅点的写法:

CC			= arm-linux-gcc
LD 			= arm-linux-ld
OBJCOPY		= arm-linux-objcopy
CFLAGS		= -Wall -g

TARGET		:= main

TOP_DIR 	:= $(shell pwd)
# SRC_DIRS 	:= $(shell ls -F | grep /$)
SRC_DIRS 	:= $(shell find $(TOP_DIR) -maxdepth 1 -type d)

C_SRCS		= $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.c))
C_HEADS		= $(patsubst %.c, %.h, $(C_SRCS))
C_OBJS		= $(patsubst %.c, %.o, $(C_SRCS))
C_OBJS		+= $(TOP_DIR)/start.o

$(TARGET):$(C_OBJS)
	$(shell if [ ! -d $(TOP_DIR)/OBJ ]; then mkdir $(TOP_DIR)/OBJ; fi)
	$(LD) -Ttext=0x42C00000 $^ -o OBJ/$@.elf
	$(OBJCOPY) -I elf32-littlearm -Obinary OBJ/$@.elf OBJ/$@.bin

%.o:%.c %.h
	$(CC) -c -o $@ $<

%.o:%.s
	$(CC) -c -o $@ $<

.PHONY:clean
clean:
	rm -rf $(C_OBJS) OBJ/*.*

测试这段优雅的Makefile后,发现生成的.bin文件下载到板子上运行不了。
原来,ld链接器对文件顺序是有要求的,从左到右,如果a依赖b,则a应该放在b的左边,ld a b,上面的例子,start.o是启动文件,所以start.o应该放在最前头;

C_OBJS		= $(patsubst %.c, %.o, $(C_SRCS))
C_OBJS		+= $(TOP_DIR)/start.o

替换成

C_OBJS		= $(TOP_DIR)/start.o $(patsubst %.c, %.o, $(C_SRCS))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值