1.make的使用语法
make [选项] [目标] [宏定义]
常用选项 | 特性 |
-d | 显示调试信息 |
-f<文件> | 制定从哪个文件中读取依赖关系信息。 默认文件是“Makefile”或“makefile”。 “-”表示从标准输入 |
-h | 显示所有选项的简要说明 |
-n | 不运行任何Makefile命令,只显示他们 |
-s | 安静的方式运行,不现实任何信息 |
2.Makefile的编写原则和规则
(1)编写规规
- 当make 命令不带选项运行时,它从Makefile中读取指定规则。
- 当指定规则在不同于Makefile(或makefile)的其他文件中时,就要运行带有-f选项的make命令,比如make。fray。Makefile
(2)编写规则
1)规则一
目标列表:关联性列表 <TAB>命令列表 |
- 目标列表:是用一个或多个空格分开的目标文件的清单。
- 关联性列表(也称先觉条件):同样是一个或多个空格分开的目标文件,是目标列表所以来的多个目标文件的清单。
- 命令列表:用于创建目标文件的将要执行的命令清单,这些命令被换行符隔开。命令列表中的每个命令必须以<Tab>字符开始。
2)规则二
目标列表:关联性列表;命令列表 |
- 命令列表是一系列被分号隔开的命令。一个很长的命令行要续行时可以用反斜线符号。
- 命令列表示例:
cd /home/momo/priv/bin;rm file1 file2\ lab2 lab3\ prog1.c prog2.c prog5.c |
等同于
cd /home/momo/priv/bin;rm file1 file2 lab2 lab3 prog1.c prog2.c prog5.c |
- Makefile中可是哟个shell中的一些通配符:(1)注释(#)、连接符(\);(2)关联列表和命令列表中可使用shell通配符?、*等;
3.Makefile的示例
(1)示例一
#注释 power:power.c gcc -o power power.c |
(2)实例二
Makefile:
bin/mysum:obj/mymath.o obj/mysum.o
gcc -o bin/mysum obj/mymath.o obj/mysum.o
obj/mymath.o:main/mymath.c
gcc -o obj/mymath.o -Iinclude -c main/mymath.c
obj/mysum.o:func/mysum.c
gcc -o obj/mysum.o -Iinclude -c func/mysum.c
clean:
rm -f ojb/mymath.o obj/mysum.o
执行:
momo@anan:~/usr/dev/cc$ make clean
rm -f ojb/mymath.o obj/mysum.o
momo@anan:~/usr/dev/cc$ make (等价于make -f Makefile)
gcc -o obj/mysum.o -Iinclude -c func/mysum.c
gcc -o bin/mysum obj/mymath.o obj/mysum.o
4.Makefile变量的使用
(1)简单变量
- 定义
变量名:=[文本] |
这类变量的实质就是一组字符串
- 添加
变量名+=[文本] 等价于 变量名:=[文本] [文本] |
(2)引用变量
- $(变量名)
- $单字符变量
例如:
G:=gcc(注意等号两边不能有空格)
$G -o power power.c
(3)内置变量
- make中有几个内置变量,使用这些变量会使我们的工作更简单。常用的内建(内置)变量和他们的意义:
变量名 | 意义 |
$@ | 当前目标的名称 |
$? | 比当前目标更新的已修改的依赖性列表 |
$< | 依赖性列表中的第一个文件 |
$^ | 用空格分开的所有依赖性列表 |
(4)虚目标
- 不存在的我呢见,而且也无需创建他们;
- 允许你强制执行某些事件,而这些事件在正常规则中是不会发生的;
- 虚目标不是真正的文件,make命令可以使用针对他们的任意规则:
虚目标总是使之与有关的命令被执行。
- 常见的虚目标列表
目标 | 意义 |
all | 生成工程中所有可以执行者,通常是makefile的第一个生成目标 |
test | 运行程序的自动测试套件 |
clean | 删除amke all生成的所有文件 |
install | 在删除目录中安装工程项目生成的可执行文件和文档 |
uninstall | 删除make install 安装的所有文件 |
- 实例:
CC:=gcc
TARGET:=bin/mysum
OBJ:=obj/mymath.o obj/mysum.o
INCLUDE:=-Iinclude
$(TARGET):$(OBJ)
$(CC) -o $@ $^
obj/mymath.o:main/mymath.c
$(CC) -o $@ $(INCLUDE) -c $^
obj/mysum.o:func/mysum.c
$(CC) -o $@ $(INCLUDE) -c $^
clean:
rm -f $(OBJ)
执行:
momo@anan:~/usr/dev/cc$ make clean -f Makefile2
rm -f obj/mymath.o obj/mysum.o
momo@anan:~/usr/dev/cc$ make -f Makefile2
gcc -o obj/mymath.o -Iinclude -c main/mymath.c
gcc -o obj/mysum.o -Iinclude -c func/mysum.c
gcc -o bin/mysum obj/mymath.o obj/mysum.o
(5)特殊目标
make中有一些预定义的目标,这些预定义目标被make以一种特殊的方式进行处理,这些目标称为特殊目标。
特殊目标 | 目的 |
.DEFAULTS | 如果make找不到生成目标的任何makefile入口或后缀规则,他就执行与目标相关的命令 |
.IGNORE | 如果某一行makefile包含该目标,make忽略错误代码并继续建立,如果一个命令不正常存在,make自然会停止。 带有-i选项的make命令可以执行相同的任务。 |
.PHONY | 允许我们指定一个不是文件的目标,所以我们能指示make调用一系列makefile的命令,即使在我们当前目录有一个具有目 标名称的文件 |
.SILENT | make执行这些命令但不现实这些命令,带有-s选项的make可以执行相同的任务。如前面所讨论的,在该命令前放置一个@ 符号就可以执行一个特别的命令(不显示到桌面上) |
.SUFFIXES | 为目标指定的前提(后缀)可以与后缀规则相关联。如果与目标没有相关联的前提,已存在的后缀列表就会被删除。 |
-rw-rw-r-- 1 momo momo 9 5月 9 22:42 clean
momo@anan:~/usr/dev/cc$ cat clean
fjdlsjfl
momo@anan:~/usr/dev/cc$ make clean -f Makefile2
make: 'clean' is up to date.
如下makefile2:
CC:=gcc
TARGET:=bin/mysum
OBJ:=obj/mymath.o obj/mysum.o
INCLUDE:=-Iinclude
$(TARGET):$(OBJ)
$(CC) -o $@ $^
obj/mymath.o:main/mymath.c
$(CC) -o $@ $(INCLUDE) -c $^
obj/mysum.o:func/mysum.c
$(CC) -o $@ $(INCLUDE) -c $^
.PHONY:clean
clean:
rm -f $(OBJ)
执行:此时就可以解决之前的问题了
momo@anan:~/usr/dev/cc$ make clean -f Makefile2
rm -f obj/mymath.o obj/mysum.o
(6)默认模式规则
- make中有许多预定义的指定规则也成为后缀规则,它可以让make自动执行许多任务。
- make已经内建许多其他语言的规则和Unix使用程序(包括SCCS、RCS、ar、lex和yass)的规划。
- 为了建立一个目标,make会遍历一连串的依赖关系,这是为了决定从何处开始建立(或重建)。如果没有找到目标文件,make就按照优先顺序查找源文件。
- 为了生成目标文件,他首先查找带.c、.f或.s后缀的文件,如果一个都没找到,它会继续寻找带.c后缀的文件并继续搜索,直至找到一个源文件。如果没有找到一个源文件,make就会报告一个异常。
- 默认的模式规则(GNU make)
%o:%c:
$(CC) $(CFLAGS) -c $<
%o:%.s:
$(AS) $(ASFLAGS) -o $@ $<
- 默认的后缀规则
SUFFIXES:.o.c.s
.c.o:
$(CC) $(CFLAGS) -c $<
.s.o:
$(AS) $(ASFLAGS) -o $@ $<
实例:
Makefile2
CC:=gcc
TARGET:=bin/mysum
OBJ:=obj/mymath.o obj/mysum.o
INCLUDE:=-Iinclude
$(TARGET):$(OBJ)
$(CC) -o $@ $^
obj/%.o:func/%.c
$(CC) -o $@ $(INCLUDE) -c $^
#obj/mymath.o:func/mymath.c
# $(CC) -o $@ $(INCLUDE) -c $^
#obj/mysum.o:func/mysum.c
# $(CC) -o $@ $(INCLUDE) -c $^
.PHONY:clean
clean:
rm -f $(OBJ)