一般来说,只需要在命令行输入make就行,然后make就在当前文件夹中寻找makefile
有时候你需要make来编译某一段文件,而不是整个工程;
有时候不同的编译需要不同的规则
0 | 成功执行 |
---|---|
1 | 在make时出现的任何错误都会返回1 |
2 | 如果使用的是make -q的选项,并且make使得一些 目标不需要更新,就会返回2 |
有时候我们的makefile的名字并不是:makefile 或者是 Makefile
这时候使用make -f命令,例如makefile的名字是 bond.mk
make -f bond.mk
make -f也可以连续的多次使用,当你同时编译多个mk文件时:
make -f common.mk -f project1.mk -f project2.mk
我们知道make每次编译形成的最终目标通常就是第一个目标
但是在第一个目标也有可能是许多目标共同组成的,那么如何去在这么多”第一个“目标中去寻找我想要编译的呢?
可以给make一个指示
通过环境变量MAKECMDGOALS,这个变量存放的就是最终编译目标的列表
如果没有给MAKECMDGOALS指定值,那么这就是个空值
source = 1.c 2.c
ifndef ($(MAKRCMDGOALS),clean)
include ( ( ((source): .c = .d)
endif
表示如果没有执行make clean这个命令,makefile就会包含1.d和2.d这两个makefile
使用指定编译最终目标的方法可以更方便的编译我们的程序
.PHONY all
all : para1 para2 para3
如果我们要编译所有的目标就直接make,就会默认第一个目标all,伪目标也是目标
如果要单独编译某一个目标,make para2
有没有类似make clean这种单独指示一个伪目标编译的
伪目标 | 作用 |
---|---|
all | 编译所有目标 |
clean | 清楚所有编译好的目标 |
install | 把目标的执行文件拷贝到指定的目标中去 |
列出改变过的源文件 | |
tar | 把源程序打包备份 |
dist | 把tar文件压缩成Z文件或者是gz文件 |
TAGS | 更新所有目标,以备重新完整的编译使用 |
check | 测试makefile的流程 |
test | 测试makefile的流程 |
make的命令参数 | 用法 |
---|---|
-n / --just-print / --dry-run / --recon | 有时候我们不希望我们的规则执行,但是我们在终端想看makefile中的其中一种规则,就得使用检查规则 |
-t / --touch | 把目标文件的时间更新,但不改变目标文件 |
-q / --question | 来检查目标是否需要重新构建,返回0表示目标是最新的,不需要重新构建;返回非0,表示目标文件需要重新构建 |
-v / --version | 输出make程序的版本、版权等关于make的信息 |
-b / -w | 忽略和其他版本make的兼容性 |
-B / --always-make | 重编译 |
“-C < dir> / --directory=< dir> | 指定读取 makefile 的目录。如果有多个“-C”参数,make -C ~hchen/test -C prog等价于make -C ~hchen/test/prog |
-d | 输出所有的调试信息。(会非常的多) |
-e / --environment-overrides | 指明环境变量的值覆盖 makefile 中定义的变量的值 |
-f < file> | 指定需要执行的 makefile。 |
-h / --help | 显示帮助信息 |
-i / --ignore-errors | 在执行时忽略所有的错误 |
-I< dir> / --include-dir=< dir> | 告诉make在指定的目录中搜索头文件,通常在编译过程中指定额外的头文件搜索路径 |
-j[number] / --jobs[number] | 例如,make -j4 表示使用 4 个作业并行构建。make 命令将尝试并行地构建多个目标 |
-k / --keep-going | 表示出错也不会停止运行 |
-s / --silent / --quiet | 在命令运行时不输出任何命令 |
一般来说一个模式只用一个%去代表前缀、后缀、或者能代表一个或者多个字符
举个例子:
%.o : %.c
$(CC) -c $(CPPFLAGS) ( C F L A G S ) ? D (CFLAGS) -D (CFLAGS)?D(date)
也可以取消内建的隐含规则,只要不再后面写命令
%.o : %c
双后缀定义了一对后缀:目标文件的后缀和依赖目标的后缀
而且这一对连起来的后缀是由make认识的,
“.c.o” 相当于 “%.o : %.c”
.c.o : foo.h
表示:%.o : %.c foo.h
注意c和o的位置关系
单后缀规则只定义了一个后缀,也就是源文件的后缀。
其中一个依赖目标后缀是make所认识的
“%.c"相当于”% : %.c"
后缀规则中,如果没有命令那将毫无意义
要想make知道有哪些后缀需要认识,我们可用伪目标:.SUFFIXES来定义后缀或是删除
.SUFFIXES : .hack .win
把hack和win加入后缀列表的末尾,定义自己的后缀
.SUFFIXES : 删除默认的后缀
或者使用 make -r或者是 -no-builtin-rules
有些默认后缀是make所认识的呢:
.c:C语言源文件
.o:目标文件
.h:头文件
.cpp:C++源文件
.cc:C++源文件
.cxx:C++源文件
.C:C++源文件
.s:汇编语言源文件
.S:汇编语言源文件
函数库文件也就是对目标文件的中间文件进行打包工作
一般是由命令“ar”来完成打包工作
一个函数库文件可以有许多的文件组成,我们可以指定文件来组成函数库文件
archive(member)一般这种用法就是为 ar 所服务的
单一文件组成库文件
foolib(hack.o) : hack.o
ar cr foolib hack.o
多个文件组成库文件,中间用空格分开
foolib(hack.o kludge.o) : hack.o kludge.o
ar cr foolib hack.o kludge.o
还可以使用Shell的文件通配符来定义
foolib(*.o)
可以使用 后缀规则和隐式规则来生成函数库打包文件:
.c.a :
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $*.o
$(AR) r $@ $*.o
$(RM) $*.o