标签:image 匹配 提示 多次 定义 嵌入 必须 png 转义
makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile的好处就是:
—“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。二、节约编译时间(没改动的文件不编译)。
make是一个命令工具,是一个解释makefile中指令的命令工具。
一个简单的Makefile文件包含一系列的规则,其样式如下:
target:prerequisites
command
...
...
=====================
目标 : 依赖文件
[tab键] 命令
...
...
这是一个文件依赖关系,也就是说target是由一个或多个目标文件依赖于prerequisites中的文件,其生成规则定义在command中,而且只要prerequisites中有一个以上的文件比target文件更新的话,command所定义的命令就会被执行,这是makefile的最基本规则,也是makefile中最核心的内容。
我们仍然以hello.c文件为例:
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("Hello World!\n");
return 0;
}
然后编写Makefile(这里使用的是gcc、而不是arm-linux-gcc):
ALL: hello.o
hello.o: hello.c
gcc hello.c -o hello.o
编译并执行:
make
./hello.o
例如:
SRC = $(wildcard ./*.c)
匹配目录下所有的 .c 文件,并将其赋值给 SRC 变量。
pat 是 pattern 的缩写,subst 是 substring 的缩写。
参数 “TEXT ”单词之间的多个空格在处理时被合并为一个空格,并忽略前导和结尾空格。
例如:
OBJ = $(patsubst %.c, %.o, $(SRC))
这个函数有三个参数,意思是取出 SRC 中所有的值,然后将 “.c” 替换为 “.o”,最后赋值给 OBJ 变量。
函数“foreach ”不同于其它函数。它是一个循环函数。类似于 Linux 的 shell 中的for 语句:
“filter”函数可以用来去除一个变量中的某些字符串, 我们下边的例子中就是用到了此函数。
1).找出符合PATTERN 格式的值
2).找出不符合PATTERN 格式的值
假如我们目录下有很多个 “.c” 后缀的源文件,就不需要写很多条规则语句了,
我们修改我们的Makefile文件:
SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
ALL: hello.out
hello.out: $(OBJ)
gcc $(OBJ) -o hello.out
$(OBJ): $(SRC)
gcc -c $(SRC) -o $(OBJ)
这里我们先将所有的 “.c” 文件编译为 “.o” 文件,这样后面更改某个 “.c” 文件时,其它的 “.c” 文件将不再编译,而只是编译有更改的 “.c” 文件,可以大大节约大项目中的编译速度。
需要注意的是:
Makefile 中也有一些已经定义好的常用变量,这里介绍其中常用的3个。
表示规则中目标,例如 hello.out
表示规则中的第一个依赖条件,例如 hello.c
表示规则中的所有依赖条件,由于我们示例中都只有一个依赖条件,这种情况下 $^ 和 $< 区别不大
我们修改我们的Makefile文件:
SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
ALL: hello.out
hello.out: $(OBJ)
gcc -o $@ $<
$(OBJ): $(SRC)
gcc -c -o $@ $<
我们可以编译一条属于自己的 clean 语句,来清理 make 命令所产生的所有文件。例如
SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
ALL: hello.out
hello.out: $(OBJ)
gcc -o $@ $<
$(OBJ): $(SRC)
gcc -c -o $@ $<
clean:
rm -rf $(OBJ) *.out
这样我们就可以使用make clean 命令来清理生成的文件了:
提示:make命令是可以带上目标名的,如果make后面不跟目标名字的话,默认生成第一个目标,当带上目标名的话,生成指定的目标。
上面我们写了一个 clean 语句,使得我们执行 “make clean” 命令的时候,可以清理我们生成的文件。
但是假如还存在一个文件名就是 clean 文件,那么我们再执行 “make clean” 命令的时候就只是显示:
make clean
make: `clean‘ is up to date.
为什么?我们看一看Makefile的核心规则:
但是现在目录中有名为clean的文件,那目标文件存在,那就取决于依赖,但是在Makefile中clean目标没有依赖,所以没有办法通过判断依赖的的时间去更新clean目标,所以clean目标文件一直都是目录中那么clean文件。所以说,如果目录中有何clean同名文件时就没有办法执行clean操作了。
解决方法就是我们使用伪目标,把这个目标定义为假想目标这样就可以避免出现上面的问题了,例如:
SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
ALL: hello.out
hello.out: $(OBJ)
gcc -o $@ $<
$(OBJ): $(SRC)
gcc -c -o $@ $<
clean:
-rm -rf $(OBJ) hello.out
.PHONY: clean ALL
通常,我们也会把 ALL 也设置为伪目标。
变量的种类分为:
延时变量:例子:赋值方式:A =xxx #A的值在使用到的时候才会确定
比如我们编写Makefile文件:
A:=$(C)
B=$(C)
C=123
ALL:
@echo A=$(A)
@echo B=$(B)
C赋值给A、但是C现在的值为空,B是延时变量,等到用到时才确定,所以执行到C=123才会显示B的值,也就是123.
参考文章
标签:image 匹配 提示 多次 定义 嵌入 必须 png 转义
原文地址:https://www.cnblogs.com/zyly/p/14827987.html