Make脚本的基础
Makefile中的变量,就像是C/C++语言中的宏一样,代表文本字符串,在Makefile中执行的时候会自动原样地展开在所使用的地方。
其与C/C++的宏所不同的是可以在Makefile中改变其值。在Makefile中,变量可以使用在目标、依赖目标、命令或是Makefile的其它部分中。
变量的命名可以包含字符、数字、下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空白字符(空格、回车等)。
变量名对大小写敏感,传统的变量名是全大写的命名方式。
变量的定义格式
变量名 赋值符号 变量的值
赋值符号有三种:
= 直接将后面的字符串赋给变量
:= 后面跟变量,将它的内容赋给变量
+= 变量原来的值+空格+后面的字符串=>新的变量值
例如
CC = arm-linux-gcc
Echo $(CC)
常用的为 = +=
变量的引用
变量引用的三种格式:
$(变量名)
${ 变量名}
当变量名为单个字符时,可以省略括号
make处理变量时会扫描一遍整个Makefile,确定所有变量的值,因此变量的使用可以在定义之后,而且使用的是最后一次赋予的值。
例:
objects = program.o foo.o utils.o program : $(objects) gcc -o program $(objects)
变量的定义可以出现在三个地方
在makefile中定义
在make命令行中定义
使用shell环境中的定义
优先级:
make命令行中定义 > 在makefile中定义 > 使用shell环境中的定义 > 预定义的变量
在Makefile中的CC= xxxxxx就会失效而执行 make后面的语句
make有许多预定义的变量,这些变量具有特殊的含义,可在规则中直接使用。¥
1.$*不包含扩展名的目标文件名称
Main.o 可以写成$*
2.$+所有的依赖文件,空格分开,并以出现的先后为序,可能包含重复的依赖文件
3.$<第一个依赖文件的名称
4.$?所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚
5.$@目标的完整名称
6.$`所有的依赖文件,以空格分开,不包含重复的依赖文件
7.$%如果目标是归档成员,则该变量表示目标的归档成员名称,例如,如果目标文件为
Mytarget.so(p_w_picpath.o)。则$@为mytarget.so。而$%为p_w_picpath.o
1.条件表达式的语法为:
conditional-directive
text-if-trueendif
其中conditional-directive表示条件关键字,如“ifeq”。Makefile所支持的关键字有四个
ifeq
ifneq
ifdef
ifndef
2.for k in $(DIRS) ; do ……
k依次取变量DIRS中的每一个值,执行do后面的语句
例:
SUBDIRS=temp1 temp2
for i in $(SUBDIRS);
Do
make-C $$i||exit $?;
done
3.wildcard函数(通配符函数),其形式是:
$(wildcard _pattern)
通过该函数可得到当前工作目录中满足_pattern模
式的文件或目录名列表。如:
SRCS:=$(wildcard *.c)
subst函数,格式为:$(subst <from>, <to>, <text>)
该函数把字符串<text>中的<from>字符串替换为<to>。函数返回被替换后的字符串。
patsubst函数,格式为:
$(patsubst <pattern>, <replacement>, <text>)
查找<text>中的单词(单词以“空格”、“Tab”、“回车”分隔)是否符合模式<pattern>,若匹配的话,则以<replacement>模式替换,<pattern>可以包含通配符”%”,表示任意长度的字符串。若<replacement>中也包含“%”,则其所代表的的即为<pattern>中的那个“%”所代表的的字符串。如:
OBJS:=$(patsubst %.c, %.o, x.c.c bar.c)
函数返回结果为:x.c.o bar.o
例: SRCS:=$(wildcard *.c)
OBJS:=$(patsubst %.c,%.o,$(SRCS))
……
hello: $(OBJS)
$(CC) -o $@ $(OBJS)
模式规则(pattern rules)。这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。模式规则看起来非常类似于正则规则,但在目标名称的前面多了一个 % 号,同时可用来定义目标和依赖文件之间的关系,例如下面的模式规则定义了如何将任意一个 X.c 文件转换为 X.o 文件
%.o:%.c
$(CC) $(CCFLAGS) $(CPPFLAGS) -c -o $@ $<
在makefile中,目标分为两类:实目标和伪目标
实目标--真正要生成、以文件形式放在磁盘上的目标。
例:
main.o:mai.c
$(CC) $(CCFLAGS) -c -o $@ $<
伪目标--不要求make生成实际的文件,而是使make程序执行一些与创建和维护目标文件没有直接联系的辅助性操作,如打印信息、删除文件。
例:
clean: rm *.o
为了避免和文件重名的这种情况,可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”
.PHONY: cleanclean: rm *.o temp
外一个使用假想目标的例子是使用make的递归调用进行连接的情况:此时,makefile文件常常包含列举一系列需要创建的子目录变量。例:
subdirs: for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir; \ done
伪目标也可以有依赖,例 :
.PHONY : all
all : prog1 prog2 prog3 prog1 : prog1.o utils.o cc -o prog1 prog1.o utils.o prog2 : prog2.o cc -o prog2 prog2.o ……
缺省情况下,当make寻找makefile文件时,它试图搜寻具有如下的名字的文件,按顺序:‘GNUmakefile’、‘makefile’和‘Makefile’。
如果您使用非标准名字makefile文件,您可以使用‘-f’或‘--file’参数指定您的makefile文件。参数‘-f name’或‘--file=name’能够告诉make读名字为‘name’的文件作为makefile文件
在makefile后,就可以调用make命令生成和维护目标文件。命令格式为:
Make [option] [macrodef] [target]
- Option指定make工作的行为
- Macrodef给出执行makefile时的宏值
- Target是makefile中的目标之一
GNU的make工作时的执行步骤
- 读入所有的Makefile
- 读入被include的其它Makefile
- 初始化文件中的变量
- 推导隐晦规则,并分析所有规则
- 为所有的目标文件创建依赖关系链
- 根据依赖关系,决定哪些目标要重新生成
- 执行生成命令
第一步:编辑源文件
#vi hello.c
第二步:建立makefile
#vi makefile
第三步:编辑makefile
(同一目录下有多个.C文件,这些.C文件最后链接成可执行程序hello)
BIN=hello
SRCS:=$(wildcard *.c)
OBJS:=$(patsubst %.c,%.o,$(SRCS))
CC=gcc
all:$(BIN)
$(BIN):$(OBJS)
(CC) -o $(EXECPROGRAM) $(OBJS)
%.o:%.c
$(CC) -c -o $@ $<
clean:
rm –rf *.o $(BIN)
Linux下的图形开发工具
Eclipse
Code blocks
Linux下的应用程序调试工具
Gdb
printf