日期:2014-05-16  浏览次数:20731 次

makefile里的超长变量的拆分
问题貌似很简单,可我折腾了一个周末也搞不定,惭愧啊。

公司有一个makefile已经用了很多年,里面有这么一行:
something: $(OBJS)
echo $(OBJS) >> tmpfile

本来一直很正常的能写进文件,但是几年下来这个变量OBJS越来越长,现在有几万个字符,终于写不进文件了,估计是命令的缓冲区不够用了。

于是我打算把这个变量拆开。最先尝试的是:
echo -e $(foreach x, $(OBJS), $(x)\\\n) >> tmpfile
还有
$(foreach x, $(OBJS), echo $(x) >> tmpfile;)

运行的结果和修改之前类似,但是如果我把$(OBJS)换成一个短的变量就可以,看来即使循环也同样存在缓冲区的问题。

接下来我又想到了awk
echo $(OBJS) | awk -F " " '{ ORS=" "; for (i=1;i<=300;i++) print $i }' >> tmpfile
echo $(OBJS) | awk -F " " '{ ORS=" "; for (i=301;i<=NF;i++) print $i }' >> tmpfile
我在bash里面试了可以成功,没想到在makefile里面就不灵了。后来我发现awk接收到的$0、$1、$NF全都是空的。这次就不是变量大小的问题了,因为我试了一个小的变量也是同样的结果。难道makefile里面的管道不是这么用的?

用cut应该比awk还简单,
echo $(OBJS) | cut -d " " -f 1-300
echo $(OBJS) | cut -d " " -f 301-
但是我的环境里面没有cut,而且即使有也可能遇到同样的管道问题。

当然还有一个思路就是把$(OBJS)的各个部分各自写入文件,但是那样不但涉及到目录结构太复杂,而且以后每次修改这个变量的时候还得记得修改这个写文件的操作,不好维护。

高手们有什么好办法吗?多谢了!
------解决方案--------------------
你这问题是得重构代码结构啊。这代码结构九成componentize得不好。