关于makefile

Makefile 规则格式

命令列表中的每条命令必须以 TAB 键开始,不能使用空格!

   目标…... : 依赖文件集合……
   		命令 1
   		命令 2
   		……

Make 的执行过程:
1. make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
2. 当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件
3. 当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比
目标文件晚)的话就会执行后面的命令来更新目标

Makefile 变量

1 #Makefile 变量的使用
2 objects = main.o input.o calcu.o
3 main: $(objects)
4 gcc -o main $(objects)
 

变量的引用方法是“$(变量名)”,

=

使用“=”在给变量的赋值的时候,不一定要用已经定义好的值,也可以使用后面定义的值

“:=”

这是因为赋值符“:=”
不会使用后面定义的变量,只能使用前面已经定义好的,这就是“=”和“:=”两个的区别。

?=
如果变量 curname 前面没有被赋值,那么此变量就是“zuozhongkai”,如果前面已经赋过值了,那么就使用前面赋的值。

“+=”
Makefile 中的变量是字符串,有时候我们需要给前面已经定义好的变量添加一些字符串进去,此时就要使用到符号“+=”

在这里插入图片描述

常用的三种:$ @、 $ <和 $ ^,

我们直接看写好的makefile

   目标…... : 依赖文件集合……
   		命令 1
   		命令 2
   		……

“$^”的意思是所有依赖文件的集合

arm-linux-gnueabihf-ld -Ttext 0X87800000 -o ledc.elf $^

相当于

arm-linux-gnueabihf-ld -Ttext 0X87800000 -o ledc.elf start.o main.o

“$@”的意思是目标集合

arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@

相当于

arm-linux-gnueabihf-objcopy -O binary -S ledc.elf ledc.bin

“$<”的意思是依赖目标集合的第一个文件

%.o:%.s
 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

相当于

start.o:start.s
 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o start.o start.s

makefile的函数

Makefile 支持函数,类似 C 语言一样,Makefile 中的函数是已经定义好的,我们直接使用,
不支持我们自定义函数。make 所支持的函数不多,但是绝对够我们使用了,函数的用法如下:

$(函数名 参数集合)

或者

${函数名 参数集合}

可以看出,调用函数和调用普通变量一样,使用符号“ ” 来 标 识 。 参 数 集 合 是 函 数 的 多 个 参 数 , 参 数 之 间 以 逗 号 “ , ” 隔 开 , 函 数 名 和 参 数 之 间 以 “ 空 格 ” 分 隔 开 , 函 数 的 调 用 以 “ ”来标识。参数集合是函数的多个 参数,参数之间以逗号“,”隔开,函数名和参数之间以“空格”分隔开,函数的调用以“ ,”开

patsubst

patsubst函数
用来完成模式字符串替换

 $(patsubst <pattern>,<replacement>,<text>)

此函数查找字符串 中的单词是否符合模式,如果匹配就用来
替换掉,可以使用包括通配符“%”,表示任意长度的字符串,函数返回值就是替换后
的字符串。如果中也包涵“%”,那么中的“%”将是中的
那个“%”所代表的字符串,比如:

$(patsubst %.c,%.o,a.c b.c c.c)

将字符串“a.c b.c c.c”中的所有符合“%.c”的字符串,替换为“%.o”,替换完成以后的字
符串为“a.o b.o c.o”。

如:

INCDIRS 		:= imx6ul \
				   bsp/clk \
				   bsp/led \
				   bsp/delay  \
				   bsp/beep	\
				   bsp/key	\
				   bsp/gpio	
INCLUDE			:= $(patsubst %, -I %, $(INCDIRS))

给每个INCDIRS加上 -I

wildcard

  1. 函数 wildcard
    通配符“%”只能用在规则中,只有在规则中它才会展开,如果在变量定义和函数使用时,
    通配符不会自动展开,这个时候就要用到函数 wildcard,使用方法如下:
$(wildcard PATTERN…)

比如:

$(wildcard *.c)

上面的代码是用来获取当前目录下所有的.c 文件,类似“%”。

  1. 函数 foreach
    foreach 函数用来完成循环,用法如下:
    $(foreach , , )
    此函数的意思就是把参数中的单词逐一取出来放到参数 中,然后再执行
    包含的表达式。每次 都会返回一个字符串,循环的过程中, 中所包含的每个字符串
    会以空格隔开,最后当整个循环结束时, 所返回的每个字符串所组成的整个字符串将会是
    函数 foreach 函数的返回值。
SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

这里的意思先是使用foreach 找到SRCDIRS下所有的目录,然后在通过wildcard 获取当前目录下所有的.s和.c 文件

函数 notdir

看名字就是知道去除文件中的目录部分,也就是提取文件名,用法如下:

$(notdir <names…>)

此函数用与从文件名序列中提取出文件名非目录部分,比如:

$(notdir </src/a.c>)

提取文件“/src/a.c”中的非目录部分,也就是文件名“a.c”。

SFILENDIR		:= $(notdir  $(SFILES))
CFILENDIR		:= $(notdir  $(CFILES))

这里面提取到没有路径的.c和.s

后面我这里在调用把.和.c换成.o

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

这里就是obj/xxx.o了

VPATH

VPATH := $(SRCDIRS)

VPATH 是指定搜索目录的,这里指定的搜素目录就是变量 SRCDIRS 所保存的
目录,这样当编译的时候所需的.S 和.c 文件就会在 SRCDIRS 中指定的目录中查找。

Makefile 伪目标

用伪目标的主要是为了避免 Makefile 中定义的只执行命令的目标和工作目录下的实际文
件出现名字冲突,有时候我们需要编写一个规则用来执行一些命令,但是这个规则不是用来创
建文件的

clean:
	rm *.o
	rm main

上述规则中并没有创建文件 clean 的命令,因此工作目录下永远都不会存在文件 clean,当
我们输入“make clean”以后,后面的“rm *.o”和“rm main”总是会执行。可是如果我们“手
贱”,在工作目录下创建一个名为“clean”的文件,那就不一样了,当执行“make clean”的时
候,规则因为没有依赖文件,所以目标被认为是最新的,因此后面的 rm 命令也就不会执行,我
们预先设想的清理工程的功能也就无法完成。
为了避免这个问题,我们可以将 clean 声明为伪
目标,声明方式如下:
.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 $@ $<
$(COBJS) : obj/%.o : %.c

这里用到了个静态模式

$(COBJS) 意思是定义了一系列的目标文件
obj/%.o 是指明了targets的模式
%.c 是目标的依赖模式

$(COBJS) : obj/%.o : %.c 表示将所有的.c文件编译成.o文件存放在obj目录下

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Makefile是一种构建工具,用于自动化编译程序。下面是一些Makefile的基本知识点: 1. 规则:Makefile中最基本的部分就是规则。规则有两个部分,即目标和依赖。目标是要生成的文件,依赖是生成目标文件所需要的文件。例如: ``` hello: hello.c gcc -o hello hello.c ``` 这个规则中,hello是目标文件,hello.c是依赖文件。当执行make命令时,如果hello.c文件有更新,就会执行后面的命令,生成hello可执行文件。 2. 伪目标:有时我们需要定义一些不是文件的目标,这时可以使用伪目标。伪目标的作用是表示一个动作,而不是一个实际的文件。例如: ``` clean: rm -f *.o ``` 这个规则中,clean是一个伪目标,它表示执行rm -f *.o命令,删除所有.o文件。执行make clean命令就会执行这个规则。 3. 变量:Makefile中可以定义变量,以$符号引用变量的值。例如: ``` CC = gcc CFLAGS = -Wall -O2 hello: hello.c $(CC) $(CFLAGS) -o hello hello.c ``` 这个Makefile中,CC和CFLAGS是变量,$(CC)和$(CFLAGS)表示它们的值。这样做的好处是可以方便地修改编译器和编译选项。 4. 函数:Makefile中还可以定义函数,函数名以$符号开始。例如: ``` $(subst o,c,hello.o world.o) ``` 这个函数的作用是将字符串"hello.o world.o"中的所有o替换为c,返回"hello.c world.c"。 5. include指令:Makefile中可以使用include指令引入其他Makefile文件。例如: ``` include header.mk ``` 这个指令会将header.mk文件中的规则和变量加入当前Makefile中。 以上是Makefile的一些基础知识点,掌握了这些知识,就可以编写简单的Makefile文件了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值