Make使用笔记

Posted by wsxq2 on 2020-10-08
TAGS:  makeMakefile

本文最后一次编辑时间:2020-10-08 21:26:26 +0800

本文是 make 命令的使用笔记及 Makefile 的编写笔记

获取帮助的方法

make是个外部命令,所以–help、man、info命令均可用于获取make的相关帮助,除此之外,推荐几个学Makefile的好地方(也可作为参考手册):

  1. 跟我一起写Makefile — 跟我一起写Makefile 1.0 文档

  2. 《跟我一起写makefile》笔记

调试方法

详情参见Makefile常用调试方法 - LoTGu - 博客园(本部分很多内容都是从中摘取的)

@

GNU make有一个方便的功能,就是允许你为将被输出的命令标上安静模式修饰符(@),使用该修饰符后,执行的命令不会输出。但如果为了调试,自然希望输出执行的命令,所以去掉命令前的@符即可

warning函数

$(warning string)函数可以放在makefile 中的任何地方,执行到该函数时,会将string输出,方便定位make执行到哪个位置。当然string当中也可以包含变量,例如:

1
$(warning $(CC))

命令行选项

--just-print(-n)

让make读取Makefile并且输出它更新工作目标时将会执行的命令,但是不会真的执行它们。GNU make有一个方便的功能,就是允许你为将被输出的命令标上安静模式修饰符(@),但是该选项可以规避这个修饰符,从而获取更多调试信息。

-n选项被假设可以抑制所有命令的执行动作,然而这只在特定的状况下为真。实际上,你必须小心以对。尽管make不会运行命令脚本,但是在立即的语境之中,它会对shell函数调用进行求值动作。

--print-database(-p)

它会运行Makefile,显示GNU版权信息以及make 所运行的命令,然后输出它的内部数据库。数据库里的数据将会依种类划分成以下几个组:variables、directories、implicit rules、pattern-specific variables、files(explicit rules)以及vpath earch path。

--warn-undefined-variables

这个选项会使得make 在未定义的变量被扩展时显示警告信息。

因为未定义的变量会被扩展成空字符串,这常见于变量名称打错而且很长一段时间未被发现到。

这个选项有个问题,这也是为什么我很少使用这个选项的原因,那就是许多内置规则都会包含未定义的变量以作为用户自定义值的挂钩。

所以使用这个选项来运行make必然会产生许多不是错误的警告信息,而且对用户的makefile 没有什么用处。

--debug 

当你需要知道make 如何分析你的依存图时,可以使用–debug 选项。除了运行调试器,这个选项是让你获得最详细信息的另一个方法。你有五个调试选项以及一个修饰符可用,分别是:basic、verbose、implicit、jobs、all 以及makefile。

如果调试选项被指定成–debug,就是在进行basic 调试;如果调试选项被指定成-d,就是在进行all调试;如果要使用选项的其他组合,则可以使用–debug=option1,option2 这个以逗号为分隔符的列表,此处的选项可以是上述的任何一个单词(实际上,make 只会查看第一个字母)。

-j

make支持使用-j参数多线程构建目标以提高效率,但是,这样标准输出会比较混乱,不便于高度,因此我们需要单线程:

1
make -j1

--no-print-directory

make支持使用该参数来取消打印以人的Enter … directory和Leave .. directory信息,但是这非常不便于调试,所以我们可以关闭该选项以明确make进入了哪个目录调用的Makefile

调试技巧

Makefile中增加调试选项

1
2
3
4
5
6
7
8
Q:=@
THISFLAG := --no-print-directory
ifeq ($(D),1)
    NPROCS:=1
    Q:=
    THISFLAG:=
endif
export Q

写目标及要执行的命令时:

1
2
3
4
5
6
7
8
9
10
11
12
13
all: sicuggio.bin DB WUI
    @echo
    @echo "TARGET all: start..."
    $(Q)rm -f $(BIN_DIR)/sicuggio.*
    $(Q)$(RM) -fr $(VERS)
    $(Q)$(RM) -fr $(FW_DIR)/mkrom
    $(Q)$(RM) -fr $(CONFIG)/mkrom
    $(Q)gcc $(FW_DIR)/genrom.c $(FW_DIR)/buildrom.c -o $(FW_DIR)/mkrom -lcrypto
    $(Q)make -j$(NPROCS) -f $(PATH_BUILD)/Mk
    $(Q)rm -fr  $(CONFIG)
    @echo "compile done! compile done! compile done!"
    @echo "TARGET all: end!"
@echo

注意其中的echo命令没有必要重复输出(即使是调试)

执行make命令时:

1
make D=1

即可开启调试模式,使用单线程、输出执行的命令、显示进出的目录

制作一个用来输出变量的makefile

参见如何调试makefile变量 | 酷 壳 - CoolShell

链接

下面总结了本文中使用的所有链接: