Makefile编写

grep 函数查找文件中字符串

在一个很大的项目中想要找到一个名为is_exit_status_bad()的函数的位置,可以使用grep函数来实现。

在项目路径下分别查找当前路径、一级目录和二级目录下文件的内容:

$ grep "is_exit_status_bad()" ./*.*

$ grep "is_exit_status_bad()" ./*/*.*
	./src/nemu-main.c:int is_exit_status_bad();
	./src/nemu-main.c:  return is_exit_status_bad();
$ grep "is_exit_status_bad()" ./*/*/*.*
	./src/utils/state.c:int is_exit_status_bad() {
$ grep "is_exit_status_bad()" ./*/*/*/*.*

$ 的用法

参考链接

用法一:$0, $?等表示各种参数
用法二:${}, 获取变量的值

最常见的应该是:echo $PATH了,表示打印该shell中存在的环境变量。 ${var_name} 跟 $var_name差不多,但是用 ${ }会比较精确的界定变量名称的范围。

用法三:$()

在bash中,$( )与``(反引号)都是用来作命令替换的,执行括号或者反引号中的命令, 然后返回结果。比如:

echo "present dir is $(pwd)"

输出如下:

/> echo "present dir is $(pwd) ."
present dir is / .

echo 和 @echo

@这个符串通常用在“规则”行中,表示不显示命令本身,而只显示它的结果。

  • echo:会在shell中显示echo这条命令和这条命令的输出结果;
  • @echo:不会在shell中显示echo这条命令,但是会显示命令的输出结果。

Makefile 中的@±符号

参考链接

1)make中命令行前面加上减号

-means ignore the exit status of the command that is executed (normally, a non-zero exit status would stop that part of htat build)
通常情况下,Makefile在执行到某一条命令时,如果返回值不正常,就会退出当前make进程,通常结合 rm mkdir命令使用,(空文件或者文件不存在都会返回错误)
就是,忽略当前此行命令执行时候所遇到的错误。
而如果不忽略,make在执行命令的时候,如果遇到error,会退出执行的,加上减号的目的,是即便此行命令执行中出错,比如删除一个不存在的文件等,那么也不要管,继续执行make。

2)make中命令行前面加上@

@suppress the normal ‘echo’ of the command that is executed. 通常makefile执行到每一行时都会打印出该行信息,加上@符号后就可以不现实该条命令。 通常结合 @echo 来使用表示当前Makefile执行到哪里。
就是,在make执行时候,输出的信息中,不要显示此行命令。
而正常情况下,make执行过程中,都是会显示其所执行的任何的命令的。如果你不想要显示某行的命令,那么就在其前面加上@符号即可。

3)make中命令行前面加上加号+

+means execute this comand under make -n (when commands are not normally executed)
对于命令行前面加上加号+的含义,表明在使用 make -n 命令的时候,其他行都只是显示命令而不执行,只有+ 行的才会被执行。

Makefile中:=, =, ?=和+=的含义

参考链接

$ @、$ < 等变量的含义

参考链接

变量 含义
$# 传给脚本的参数个数
$0 脚本本身的名字
$1 传递给该shell脚本的第一个参数
$2 传递给该shell脚本的第二个参数
$@ 传给脚本的所有参数的列表,代表目标文件(target)
$* 以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过 9 个
$$ 脚本运行的当前进程ID号
$? 显示最后命令的退出状态, 0 表示没有错误,其他表示有错误
$^ 代表所有的依赖文件(components)
$< 代表第一个依赖文件(components中最左边的那个)

call 函数

call函数是唯一一个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。其语法是:

$(call <expression>; , <param1>; , <param2>; , <param3>; ...)

当 make 执行这个函数时,< expression > ;参数中的变量,如$ (1),$ (2),$ (3)等,会被参数< param1 >;, < param2 >;,< param3 >; 依次取代。而;的返回值就是 call函数的返回值。例如:

reverse = $(1) $(2)
foo = $(call reverse,a,b)

那么,foo的值就是“a b”。当然,参数的次序是可以自定义的,不一定是顺序的,如:

reverse = $(2) $(1)
foo = $(call reverse,a,b)

此时的foo的值就是“b a”。

patsubst 函数

参考链接

格式:$(patsubst ,, )

名称:模式字符串替换函数——patsubst。

功能:查找 中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式,如果匹配的话,则以替换。

这里,可以包括通配符“%”,表示任意长度的字串。如果中也包含“%”,那么,中的这个“%”将是中的那个“%”所代表的字串。

(可以用“\”来转义,以“%”来表示真实含义的“%”字符)
   
返回:函数返回被替换过后的字符串。

示例:

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

把字串“a.c b.c”符合模式[%.c]的单词替换成[%.o],返回结果是“a.o b.o”
make中有个变量替换引用

对于一个已经定义的变量,可以使用“替换引用”将其值中的后缀字符(串)使用指定的字符(字符串)替换。格式为“ ( V A R : A = B ) ”(或者“ (VAR:A=B)”(或者“ (VAR:A=B)(或者{VAR:A=B}”),

意思是,替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。“结尾”的含义是空格之前(变量值多个字之间使用空格分开)。而对于变量其它部分的“A”字符不进行替换。

例如:

foo := a.o b.o c.o

bar := $(foo:.o=.c)

在这个定义中,变量“bar”的值就为“a.c b.c c.c”。使用变量的替换引用将变量“foo”以空格分开的值中的所有的字的尾字符“o”替换为“c”,其他部分不变。

如果在变量“foo”中如果存在“o.o”时,那么变量“bar”的值为“a.c b.c c.c o.c”而不是“a.c b.c c.c c.c”。

wildcard 和 notdir

使用以下3个内置函数:

1、wildcard : 扩展通配符;
2、notdir : 去除路径;
3、patsubst :替换通配符。

建立一个测试目录,在测试目录下建立一个名为sub的子目录

mkdir  mk
cd mk
mkdir sub

在mk下,建立a.c和b.c 2个文件,在sub目录下,建立aa.c和bb.c 2 个文件

建立一个简单的Makefile

src=$ (wildcard *.c ./sub/*.c)
file=$ (notdir $ (src))
obj=$ (patsubst %.c,%.o,$(src) )

all:
  @echo $(src)  
  @echo $(file)
  @echo $(obj)

执行结果分析:
第一行输出:
a.c b.c ./sub/aa.c ./sub/bb.c

wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。

第二行输出:
a.c b.c aa.c bb.c
notdir把展开的文件去除掉路径信息

第三行输出:
a.o b.o aa.o bb.o

在$ (patsubst %.c,%.o,$ (src) )中,patsubst把$ (file)中的变量符合后缀是.c的全部替换成.o,
任何输出。
或者可以使用
obj=$(file:%.c=%.o)
效果也是一样的。

override 定义变量

保护Makefile中的变量不被修改,参考链接。

find函数

查找路径下文件
find 路径 -name 关键字

你可能感兴趣的:(ysyx,linux,bash,Makefile)