makefile教程(3)

2023-12-28 13:43:50

make的命令

一般来说,只需要在命令行输入make就行,然后make就在当前文件夹中寻找makefile

有时候你需要make来编译某一段文件,而不是整个工程;

有时候不同的编译需要不同的规则

make的退出码

0成功执行
1在make时出现的任何错误都会返回1
2如果使用的是make -q的选项,并且make使得一些 目标不需要更新,就会返回2

指定make编译文件

有时候我们的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每次编译形成的最终目标通常就是第一个目标

但是在第一个目标也有可能是许多目标共同组成的,那么如何去在这么多”第一个“目标中去寻找我想要编译的呢?

可以给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把目标的执行文件拷贝到指定的目标中去
print列出改变过的源文件
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:汇编语言源文件

使用make更新函数库文件

函数库文件也就是对目标文件的中间文件进行打包工作

一般是由命令“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

文章来源:https://blog.csdn.net/weixin_45241469/article/details/135265338
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。