如何调试makefile变量
六、七年前写过一篇《跟我一起写Makefile》,直到今天,还有一些朋友问我一些Makefile的问题,老实说,我有一段时间没有用Makefile了,生疏了。回顾,这几年来大家问题我的问题,其实很多时候是makefile的调试问题。所以,就像我在之前的那篇关于GDB的技巧的文章中做的一样,在这里向大家介绍一个小小的调试变量的技巧。相信一定对你有用。
对于Makefile中的各种变量,可能是我们比较头痛的事了。我们要查看他们并不是很方便,需要修改makefile加入echo命令。这有时候很不方便。其实我们可以制作下面一个专门用来输出变量的makefile(假设名字叫:vars.mk)
%: @echo '$*=$($*)' d-%: @echo '$*=$($*)' @echo ' origin = $(origin $*)' @echo ' value = $(value $*)' @echo ' flavor = $(flavor $*)'
这样一来,我们可以使用make命令的-f参数来查看makefile中的相关变量(包括make的内建变量,比如:COMPILE.c或MAKE_VERSION之类的)。注意:第二个以“d-”为前缀的目标可以用来打印关于这个变量更为详细的东西(后面有详细说明)
假设我们的makefile是这个样子(test.mk)
OBJDIR := objdir OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o) foo = $(bar)bar = $(ugh)ugh = Huh? CFLAGS = $(include_dirs) -O include_dirs = -Ifoo -Ibar CFLAGS := $(CFLAGS) -Wall MYOBJ := a.o b.o c.o MYSRC := $(MYOBJ:.o=.c)
那么,我们可以这样进行调试:
[hchen@RHELSVR5]$ make -f test.mk -f var.mk OBJS OBJS=objdir/foo.o objdir/bar.o objdir/baz.o [hchen@RHELSVR5]$ make -f test.mk -f var.mk d-foo foo=Huh? origin = file value = $(bar) flavor = recursive [hchen@RHELSVR5]$ make -f test.mk -f var.mk d-CFLAGS CFLAGS=-Ifoo -Ibar -O -O origin = file value = -Ifoo -Ibar -O -O flavor = simple [hchen@RHELSVR5]$ make -f test.mk -f var.mk d-COMPILE.c COMPILE.c=cc -Ifoo -Ibar -O -Wall -c origin = default flavor = recursive value = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
我们可以看到:
- make的第一个-f后是要测试的makefile,第二个是我们的debug makefile。
- 后面直接跟变量名,如果在变量名前加”d-“,则输出更为详细的东西。
说一说”d-” 前缀(其意为details),其中调用了下面三个参数。
- $(origin):告诉你这个变量是来自哪儿,file表示文件,environment表示环境变量,还有environment override,command line,override,automatic等。
- $(value):打出这个变量没有被展开的样子。比如上述示例中的 foo 变量。
- $(flavor):有两个值,simple表示是一般展开的变量,recursive表示递归展开的变量。
(全文完)
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《如何调试makefile变量》的相关评论
忍不住要赞美一下,太实用了
恩,相当实用
我火星了,这个网站已经关注了3年了吧, 一直觉的站长的名字很熟悉, 似乎在哪里见过, 现在终于想起来了, 过去学习Makefile就是从你那篇著名的《跟我一起写Makefile》开始的。
@jruv
关注文章就行了。是谁写的并不重要。呵呵。
这篇博文我必须拜一下,太有用了!谢谢博主。
不错,都是好的知识
非常好的知识,贵站代码高亮显示的插件是什么?我也有一个技术博客,但是里面代码高显的插件都不好用,所以想问下,非常感谢!
@eliteYang
代码高亮插件
SyntaxHighlighter Evolved
插件主页:
http://www.viper007bond.com/wordpress-plugins/syntaxhighlighter/
感谢大哥
这个很给力,或者make -n也凑合用 :)
这个强大,一下子觉得可以省掉很多功夫
信皓哥得永生
今天又学了一招。。。
博主大牛,能不能讲一下是什么原理啊
真的太实用了!节约了我至少一个小时的时间去查阅文档!!
我out了 来晚了 不过这个确实屌爆了!
请教: 我的项目里面使用的是默认的文件名makefile, 并且是在顶层目录 make -C subdir 的形式执行。
那应该怎样使用var.mk 呢?
太实用了~
I love what you guys tend to be up too. Such clever work and reporting! Keep up the amazing works guys I’ve included you guys to my own blogroll.
推荐使用 cmake更简单一些
你好,在ubuntu13.10环境下测试失败,在home目录下建立test.mk和var.mk两个文本,内容完全复制过来,在shell中输入:
make -f test.mk -f var.mk OBJS
输出显示:
make: *** No rule to make target `OBJS’. Stop.
我在man make 里也没有看到一行make语句使用两个-f的用法,请问怎么解决? 初学linux,可能问题浅显,望解答。
同样的问题
好巧妙的一招,又学习了
只能得到当前显示加载的Makefile的值,无法打印Makefile递归后最终的值
http://scc.qibebt.cas.cn/docs/linux/base/%B8%FA%CE%D2%D2%BB%C6%F0%D0%B4Makefile-%B3%C2%F0%A9.pdf 耗子叔, google第一篇就是好心人整理的你的
@nihao
我也是同样的环境,出了同样的错误提示,但是通过修改脚本,问题解决。
估计你的出错原因和我的一样:就是var.mk脚本原样拷贝到本地时,@echo前的tab键变成了空格。
解决办法:删除脚本文件@echo前的空格,输入tab。重新运行例子。
《跟我一起写Makefile》系列文章能搬运到这里来么?现在csdn感觉越来越封闭了,也许未来某一天就关闭所有博文消失了呢。
另外,这里没有给博文加分类标签的功能还是说博主自己选择了不加标签?
不灵啊
R.I.P