Makefile文件详解

目录

1、介绍

2、常用函数详解

2.1 patsubst函数

2.2 foreach函数

2.3 wildcard函数

2.4 notdir函数


1、介绍

        通过makefile的编写来管理工程文件,对工程下不同目录中的文件的编译、链接的方式、顺序进行描述。在编写makefile后,编译工程只要求输入make命令,极大的提高了编译效率。

2、常用函数详解

        (实例:正点原子imx6ul开发板,裸机开发bsp章节的makefile文件)

CROSS_COMPILE 	?= arm-linux-gnueabihf-
TARGET		  	?= bsp

CC 				:= $(CROSS_COMPILE)gcc
LD				:= $(CROSS_COMPILE)ld
OBJCOPY 		:= $(CROSS_COMPILE)objcopy
OBJDUMP 		:= $(CROSS_COMPILE)objdump

INCDIRS 		:= imx6ul \
				   bsp/clk \
				   bsp/led \
				   bsp/delay 
				   			   
SRCDIRS			:= project \
				   bsp/clk \
				   bsp/led \
				   bsp/delay 
				   				   
INCLUDE			:= $(patsubst %, -I %, $(INCDIRS))

SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
SFILENDIR		:= $(notdir  $(SFILES))
CFILENDIR		:= $(notdir  $(CFILES))

SOBJS			:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS			:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS			:= $(SOBJS) $(COBJS)

VPATH			:= $(SRCDIRS)

.PHONY: clean
	
$(TARGET).bin : $(OBJS)
	$(LD) -Timx6ul.lds -o $(TARGET).elf $^
	$(OBJCOPY) -O binary -S $(TARGET).elf $@
	$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis

$(SOBJS) : obj/%.o : %.S
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<

$(COBJS) : obj/%.o : %.c
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<
	
clean:
	rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)

        第 1~7行定义了一些变量,除了第 2行以外其它的都是跟编译器有关的,如果使用其它编译器的话只需要修改第 1行即可。第 2行的变量 TARGET目标名字,不同的例程肯定名字不一样。


        第 9行的变量 INCDIRS包含整个工程的 .h头文件目录,文件中的所有头文件目录都要添加到变量 INCDIRS中。比如本例程中包含 .h头文件的目录有 imx6ul、 bsp/clk、 bsp/delay和 bsp/led所以就需要在变量 INCDIRS中添加这些目录,即:

INCDIRS := imx6ul bsp/clk bsp/led bsp/delay

        仔细观察的话会发现第 9~11行后面都会有一个符号“ “\”,这个相当于“换行符”。


        第 14行是变量 SRCDIRS,和变量 INCDIRS一样,只是 SRCDIRS包含的是整个工程的所有 .c 和 .S 文件目录。


        第 19行的变量 INCLUDE使用 到了函数 patsubst,通过函数 patsubst给变量 INCDIRS添加一个“ “-I”,即

INCLUDE := -I imx6ul -I bsp/clk -I bsp/led -I bsp/delay

        加“ “-I”的目的是因为 Makefile语法要求指明头文件目录的时候需要加上“ “-I”。

2.1 patsubst函数

函数patsubst:

        作用:用于将文件模式进行替换。

        格式:$(patsubst 原模式, 目标模式, 文件列表)


        第 21行变量 SFILES保存工程中所有的 .s汇编文件 (包含绝对路径 ),变量 SRCDIRS已经存放了工程中所有的 .c和 .S文件,所以我们只需要从里面挑出所有的 .S汇编文件即可,这里借助了函数 foreach和函数 wildcard,最终 SFILES如下:

SFILES := project/start.S

 foreach 函数_微尘hjx的博客-CSDN博客_foreach函数

2.2 foreach函数

foreach函数的语法

格式:

        $(foreach VAR,LIST,TEXT)
函数功能:

        这个函数的工作过程是这样的:如果需要(存在变量或者函数的引用),首先展开变量“VAR”和“LIST”的引用;而表达式“TEXT”中的变量引用不展开。执行时把“LIST”中使用空格分割的单词依次取出赋值给变量“VAR”,然后执行“TEXT”表达式。重复直到“LIST”的最后一个单词(为空时结束)。“TEXT”中的变量或者函数引用在执行时才被展开,因此如果在“TEXT”中存在对“VAR”的引用,那么“VAR”的值在每一次展开式将会到的不同的值。
返回值:

        空格分割的多次表达式“TEXT”的计算的结果。


        我们来看一个例子,定义变量“files”,它的值为四个目录(变量“dirs”代表的a、b、c、d四个目录)下的文件列表:


        dirs := a b c d
        files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))


        例子中,“TEXT”的表达式为“$(wildcard $(dir)/*)”。表达式第一次执行时将展开为“$(wildcard a/*)”;第二次执行时将展开为“$(wildcard b/*)”;第三次展开为“$(wildcard c/*)”;….;以此类推。所以此函数所实现的功能就和一下语句等价:
        files := $(wildcard a/* b/* c/* d/*)

 wildcard函数_微尘hjx的博客-CSDN博客_wildcard函数

2.3 wildcard函数

wildcard函数的语法

作用: 

        扩展通配符,一般我们可以使用$(wildcard *.c)来获取工作目录下的所有的.c文件列表。

格式:

        $(wildcard PATTERN...) 

        

举例:

        $(patsubst %.c,%.o,$(wildcard *.c))

        首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表。


        第 22行变量 CFILES和变量 SFILES一样,只是 CFILES保存工程中所有的 .c文件 (包含绝对路径 ),最终 CFILES如下:

CFILES = project/main.c bsp/clk/bsp_clk.c bsp/led/bsp_led.c bsp/delay/bsp_delay.c


        第 24和 25行的变量 SFILENDIR和 CFILENDIR包含所有的 .S汇编文件和 .c文件,相比变量 SFILES和 CFILES SFILENDIR和 CFILNDIR只是文件名,不包含文件的绝对路径。使用函数 notdir将 SFILES和 CFILES中的路径去掉即可, SFILENDIR和 CFILENDIR如下:

SFILENDIR = start.S

CFILENDIR = main.c bsp_clk.c bsp_led.c bsp_delay.c

 Makefile中notdir函数使用方法_yanlaifan的博客-CSDN博客_makefile notdir

2.4 notdir函数

notdir函数的语法

作用:

        notdir用于去掉文件的绝对路径,只保留文件名。

格式:

        $(notdir 文件列表)


        第 27和 28行的变量 SOBJS和 COBJS是 .S和 .c文件编译以后对应的 .o文件目录,默认所有的文件编译出来的 .o文件和源文件在同一个目录中,这里我们将所有的 .o文件都放到 obj文件夹下, SOBJS和 COBJS内容如下:

SOBJS = obj/start.o

COBJS = obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o


        第 29行变量 OBJS是变量 SOBJS和 COBJS的集合,编译完成以后所有的 .o文件就全部存放到了 obj目录下,如下:

OBJS = obj/start.o obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o

        33-46行是.elf和.o文件的生成,就不细说了,详细看正点原子官方手册资料。


待更新...

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

内有小猪卖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值