Makefile基础知识

1. makefile中的几个重要函数

1.1 Wildcard patsubst

$(patsubst pattern,replacement,text),用于替换,函数参数有三个,

$(wildcard pattern) 返回已经存在的、使用空格分开的、匹配此模式的所有文件列表

一般使用patsubst wildcard 函数配合, 得到 .o 文件的文件名。

参考https://www.jianshu.com/p/523726ef5c3b,假设当前路径下有三个cpp文件:circle.cpp square.cpp test.cpp

SRCS = $(wildcard *.cpp)

OBJS = $(patsubst %.cpp, %.o, $(SRCS))

其中,%可以认为是匹配任意字符,%.cpp 可以用vpath 来指定匹配模式

SRCS的值就是“circle.cpp square.cpp test.cpp"

OBJS的值就是“circle.o square.o test.o”

1.2. dir 和notdir

$(dir names...)  函数的参数 names,比如是一个*.cpp的文件名,如果有多个参数,参数间用空格隔开,返回值为所有参数文件所在的所有 路径信息。官方说明如下:

Extracts the directory-part of each file name in names. The directory-part of the file name is everything up through (and including) the last slash in it. If the file name contains no slash, the directory part is the string ‘./’. For example,

$(dir src/foo.c hacks)    produces the result ‘src/ ./’.

$(notdir names...)   notdir的作用就是去掉目录信息,使得文件列表里只有文件名。

​​​​​​​1.3 addprefix

$(addprefix prefix,names...)  函数,用于对names增加前缀,前缀是固定的,names可以有多个。官方说明如下:

The argument names is regarded as a series of names, separated by whitespace; prefix is used as a unit. The value of prefix is prepended to the front of each individual name and the resulting larger names are concatenated with single spaces between them. For example,

$(addprefix src/,foo bar)    produces the result ‘src/foo src/bar’.

SRCS = $(wildcard *.cpp)

OBJS = $(patsubst %.cpp, %.o, $(SRCS))

OBJECT := $(addprefix obj/, $(notdir $(OBJS)))

OBJECT的值就是“obj/circle.o obj/square.o obj/test.o”

​​​​​​​2. Makefile中的变量

Makefile里可以用= := += 来定义变量,使用时用$(变量)获得变量的值。

如果直接用 = ,则make 会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。

“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。

+=   是添加

x = foo

y = $(x) bar

x = xyz

在上例中,y的值将会是 xyz bar ,而不是 foo bar 。

如果上述都是:= , 则 y的值将会是 foo bar

参考:https://zhidao.baidu.com/question/450144061.html

​​​​​​​3. Makefile中常用的shell命令

Shell 命令  [ ! -e $(dir $@) ]  是一个条件表达式  -e  是文件测试运算符,类似与 test命令 的功能

条件表达式要放在方括号之间,并且要有空格,例如:[$a==$b]是错误的,必须写成[ $a == $b ]

来自 <https://www.runoob.com/linux/linux-shell-basic-operators.html>

​​​​​​​4. Makefile规则

target... : prerequisites ...

        command

target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。

Prerequisites, 依赖文件,就是要生成那个target所需要的文件或是目标。

command也就是make需要执行的命令。(任意的Shell命令)

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

在command中,经常会用到三个重要的变量:

$@--表示规则中的目标文件,target

$^--表示规则中的所有的依赖文件,prerequisites

$<--表示规则中的第一个依赖文件。

参考 https://blog.csdn.net/weixin_38391755/article/details/80380786

https://blog.csdn.net/haoel/article/details/2886

​​​​​​​5. make 的工作流程

edit : main.o kbd.o command.o display.o

  gcc -o edit main.o kbd.o command.o display.o

在默认的方式下,也就是我们只输入make命令。那么,

1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。(所以,我们的makefile中,必须要把生成最终的simulation这个命令放在前面)

3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。

4、如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)

5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了。

参考 https://blog.csdn.net/haoel/article/details/2886

​​​​​​​6. vpath

如在某个目录中,除了源代码文件之外,还有不少的说明文档。如果在查找的时候,将所有的文件都判断一遍,那无疑会增加系统编译的时间。为此有时候,系统管理员不仅需要指定make命令查找的路径,而且还需要指定匹配的模式。如现在系统管理员希望make命令查找指定路径下的以.h结尾的文件。要实现这个需求,就需要用到另一个变量vpath

vpath根据所带参数的不同,这个命令主要用来完成三项工作:

(1) 什么参数都不带的情况下,指清除所有已经设置好了的文件搜索目录。注意其清除vpath命令所设置的搜索路径,而不影响VPATH变量所设置的查找路径。

(2) 带一个参数pattern,如vpath %.h。此时系统会清除符合模式的文件的搜索路径。

(3) 带两个参数,如vpath %.h ..(这个命令表示在上级目录中查找.h文件)。两个参数(匹配模式与文件的搜索路径)都带齐的话,就表示在指定的目录中按规定的模式进行查找。不过需要注意的是,这里一个模式最好对应一条语句。也就是说,在一个vpath语句中定义一个匹配模式。如果要定义多个匹配模式的话,此时最好的办法是连续使用vpath语句来定义,以指定不同的搜索策略。

有的系统中操作系统中,可以相同模式的情况下定义多个路径。如vpath %.h all、vpath %.h bll 、vpath %.h cll等等。此时后面对定义不会覆盖前面的定义。即三个语句是各自独立的,三个语句定义的变量都有效。

举例:vpath %.cpp $(dir ./*.cpp ),则makefile中其他地方使用%.cpp时,就表示只在路径./下的所有.cpp文件。

https://blog.csdn.net/zcf1002797280/article/details/50420772

​​​​​​​7. Makefile错误

makefile:2: *** missing separator. Stop.

解决方法 命令前面用TAB键,而不能用4个空格

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

123axj

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

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

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

打赏作者

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

抵扣说明:

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

余额充值