Makefile 语法学习

Makefile 语法学习

① 为什么需要 Makefile
高效地编译程序
修改源文件或头文件,只需要重新编译牵涉到的文件,就可以重新生成 APP

②Makefile语法
一个简单的 Makefile 文件包含一系列的“规则”,其样式如下:

目标(target)…: 依赖(prerequiries)…
命令(command)

`
如果“依赖文件”比“目标文件”更加新,那么执行“命令”来重新生成“目标文件”。

命令被执行的 2 个条件:依赖文件比目标文件新,或是 目标文件还没生成。

先介绍 Makefile 的 2 个函数:
A. $(foreach var,list,text)
简单地说,就是 for each var in list, change it to text。 对 list 中的每一个元素,取出来赋给 var,然后把 var 改为 text 所描述的形式。
在这里插入图片描述
B. $(wildcard pattern)
pattern 所列出的文件是否存在,把存在的文件都列出来。
在这里插入图片描述

objs := main.o sub.o

test : $(objs)
	gcc -o test $^

#需要判定是否存在依赖文件
#.main.o.d  .sub.o.d
dep_files := $(foreach f,$(objs),.$(f).d)
dep_files := $(wildcard $(dep_files))

#把依赖的文件包含起来
ifneq ($(dep_files),)
	include $(dep_files)
endif

%.o : $.c
	gcc -Wp,-MD,.$@.d -c -o $@ $^

clean:
	rm *.o test -f
distclean:
	rm $(dep_files) *.o test -f

知识点
A. make 命令的使用:
执行 make 命令时,它会去当前目录下查找名为“Makefile”的文件,并根据它的指示去执行操作,生成第一个目标。
我们可以使用“-f”选项指定文件,不再使用名为“Makefile”的文件,比如:
make -f Makefile.build

我们可以使用“-C”选项指定目录,切换到其他目录里去,比如:
make -C a/ -f Makefile.build

B. 即时变量、延时变量:
A = xxx // 延时变量
B ?= xxx // 延时变量,只有第一次定义时赋值才成功;如果曾定义过,此赋值无效
C := xxx // 立即变量
D += yyy // 如果 D 在前面是延时变量,那么现在它还是延时变量;
// 如果 D 在前面是立即变量,那么现在它还是立即变量

例如:
A = $@
test:
@echo $A

变量 A 是延时变量,它的值在使用时才展开、才确定。

上述 Makefile 中,变量 A 的值在执行时才确定,它等于 test,是延时变量。

如果使用“A := @ ” , 这 是 立 即 变 量 , 这 时 @”,这是立即变量,这时 @@为空,所以 A 的值就是空

C. 变量的导出(export):

D. Makefile 中可以使用 shell 命令:
比如:
TOPDIR := $(shell pwd)

E. 在 Makefile 中怎么放置第 1 个目标:
执行 make 命令时如果不指定目标,那么它默认是去生成第 1 个目标。
所以“第 1 个目标”,位置很重要。有时候不太方便把第 1 个目标完整地放在文件前面,这时可以在文
件的前面直接放置目标,在后面再完善它的依赖与命令。比如:
First_target: // 这句话放在前面

F. 假想目标:
我们的 Makefile 中有这样的目标:
clean:
rm -f $(shell find -name “*.o”)
rm -f $(TARGET)
如果当前目录下恰好有名为“clean”的文件,那么执行“make clean”时它就不会执行那些删除命令。
这时我们需要把“clean”这个目标,设置为“假想目标”,这样可以确保执行“make clean”时那些删
除命令肯定可以得到执行。
使用下面的语句把“clean”设置为假想目标:
.PHONY : clean

G. 常用的函数:
i. $(foreach var,list,text)
简单地说,就是 for each var in list, change it to text。 对 list 中的每一个元素,取出来赋给 var,然后把 var 改为 text 所描述的形式。
例子:
objs := a.o b.o
dep_files := $(foreach f, ( o b j s ) , . (objs), . (objs),.(f).d) // 最终 dep_files := .a.o.d .b.o.d

ii. $(wildcard pattern)
pattern 所列出的文件是否存在,把存在的文件都列出来。
例子:
src_files := $( wildcard *.c) // 最终 src_files 中列出了当前目录下的所有.c 文件

iii. $(filter pattern…,text)
把 text 中符合 pattern 格式的内容,filter(过滤)出来、留下来。
例子:
obj-y := a.o b.o c/ d/
DIR := $(filter %/, $(obj-y)) //结果为:c/ d/

iv. $(filter-out pattern…,text)
把 text 中符合 pattern 格式的内容,filter-out(过滤)出来、扔掉。
例子:
obj-y := a.o b.o c/ d/
DIR := $(filter-out %/, $(obj-y)) //结果为:a.o b.o

vi. $(patsubst pattern,replacement,text)
寻找text’中符合格式pattern’的字,用replacement’替换它们。pattern’和`replacement’
中可以使用通配符。
比如:
subdir-y := c/ d/
subdir-y := $(patsubst %/, %, $(subdir-y)) // 结果为:c d

H
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Makefile 是用于自动化编译程序的工具,它使用一种名为“规则”的方式来描述源文件和目标文件之间的依赖关系,然后根据这些规则自动编译程序。 Makefile 通常包括以下几个部分: 1. 变量定义:定义需要的变量,如编译器、编译选项等。 2. 目标文件:定义需要编译的目标文件、依赖文件和编译规则。 3. 伪目标:定义一些伪目标,如 clean、install 等。 下面是 Makefile语法: 1. 变量定义: 变量定义的语法格式为: ``` 变量名 = 变量值 ``` 例如: ``` CC = gcc CFLAGS = -Wall -O2 ``` 2. 目标文件: 目标文件的格式为: ``` 目标文件: 依赖文件 编译规则 ``` 例如: ``` main.o: main.c $(CC) $(CFLAGS) -c main.c -o main.o ``` 其中: - 目标文件是 main.o。 - 依赖文件是 main.c。 - 编译规则是 $(CC) $(CFLAGS) -c main.c -o main.o,表示使用 gcc 编译器和编译选项将 main.c 编译成 main.o。 3. 伪目标: 伪目标的格式为: ``` 伪目标: 命令 ``` 例如: ``` clean: rm -rf *.o ``` 其中: - 伪目标是 clean。 - 命令是 rm -rf *.o,表示删除所有的 .o 文件。 这些是 Makefile 的基本语法,你可以根据需要添加更多的规则来实现自动化编译。 ### 回答2: Makefile是用于自动化构建和管理软件项目的一种脚本语言,它描述了软件项目中的文件依赖关系和构建规则。Makefile文件通常包含一系列规则和命令。 Makefile的基本语法包括: 1.目标(Target):由一组规则组成,表示一个或多个文件的生成或操作。目标的命名可以是任意合法的文件名。 2.依赖(Prerequisites):目标所依赖的文件或目标。依赖可以是文件、目录或其他目标。当依赖发生变化时,相应的目标将重新生成。 3.命令(Command):规则中执行的命令。命令必须以Tab键开头,并且可以有多条。 4.规则(Rule):目标、依赖和命令的组合。规则表示了如何生成目标文件或执行一系列操作。 5.变量(Variables):用于存储常用的值或字符串,以便在Makefile中重复使用。变量以$符号开头,并用括号括起来。 6.条件判断(Conditionals):用于根据特定条件选择不同的规则或命令执行路径。条件判断以ifeq、ifneq等关键字开头。 7.循环(Loops):可以在Makefile中使用循环语句,例如foreach、while等,用于重复执行特定的操作。 Makefile的执行过程是根据文件的依赖关系来决定哪些目标需要重新生成。当执行make命令时,Makefile会被解析,并根据依赖关系构建目标文件,如果目标文件已经存在且依赖没有发生变化,则不会重新生成。 Makefile的优点是可以自动化构建过程、减少重复操作、提高项目的可维护性和可靠性。它可以根据项目的需要灵活定义构建规则,并自动处理文件间的依赖关系,大大简化了项目的管理工作和构建过程。 ### 回答3: makefile是一种用于构建和管理软件项目的工具,它使用明确的规则来指导编译和链接操作。它通常用于编译C/C++等编程语言的项目。 makefile的基本语法包含了规则、变量和命令。 规则是makefile的核心,它由目标、依赖和命令组成。目标是需要生成的文件,依赖是生成目标所依赖的文件或其他目标,命令是生成目标的具体操作。规则的格式如下: ``` 目标: 依赖 [tab] 命令 ``` 变量在makefile中用于保存常用的路径、编译选项等信息。可以通过变量的引用来简化makefile的书写和维护。变量的定义使用等号(=)来完成,如: ``` 变量名 = 值 ``` 命令是makefile中的具体操作步骤,用于生成目标。每条命令都必须以一个制表符(tab)开头,否则会被当作普通文本处理。 makefile还有一些常用的指令,如clean、all等。clean指令用于清理编译生成的目标文件和可执行文件,all指令用于编译所有文件。 makefile的优势在于可以自动判断哪些文件需要重新编译,从而提高了构建效率。它可以根据文件的修改时间和依赖关系来确定需要重新编译的文件,并只编译这些文件,避免了不必要的重复操作。 总之,makefile是一种强大的构建工具,它以简洁的语法和智能的依赖关系判断,能够实现高效的软件构建和管理。但需要注意的是,makefile语法在不同的平台和编译器上可能会有一些差异,需要根据具体情况进行调整和学习

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值