程序员是一种很懒散的动物,但这并不是说程序员不注重细节和追求相对完美
最近接到了一些脏活,给平台产品的所有组件打一个包,虽然意义不够大,但对于前端人员应该会感到比较爽,rpm包是广大“人民群众”喜闻乐见的,因为它方便部署。不过就在我接到这个任务后yum的作者,某位大神因车祸去世……
打包整理看似很简单,但实际因为涉及gnu make, bash, python, perl,rpm spec实际上要想最后打得漂亮相当困难。team里有几个古怪的程序员搞了perl发布程序,我还不能去给他做外科手术,无从下手。还有些程序员喜欢用bash做一切事情,导致这些bash又臭又长,晦涩难懂。花了两个星期,当我把最后一个提交发出后顿时感到周围清静不少,当然还要前端买帐才行。
记录一下这趟活里面值得记录的东西,之前自己很少折腾Makefile和rpm SPEC万一那天再干这种脏活,有些细节还是记不得了
1. 一定要把make的缺省规则放在第一条,在写嵌套make时总是缺省的generate target, 也就是直接调用下层make,如果下层缺省的generate target是个install target就惨了,比如在rpmbuild的时候会被install两次。
2. rpm spec中的一些shell转义字符会被rpm首先换掉 比如date ‘+%y%m%d-%H%M%S’ 出来的就是130405-070809OURCE,莫名其妙,原因是%S先被替换成了%SOURCE然后才是%S替换成秒。正确的写法是data ‘+%y%m%d-%H%M%%S’。
3. 和2类似的情况,如果想在SPEC中把某个宏注释掉,比如%configure, #%configure这样的写法是不对的,因为rpm首先是对%configure进行替换,正确的写法是#%%configure。
4. shell脚本要写得严谨些,比如下面的就不行:
[ -f /etc/a ] && .........
下面才是正确的
if [ -f /etc/a ]; then .......... ;fi
5.如果要在规则中将某个shell的执行结果作为shell变量内容要用$$:
branch=$$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/' -e 's/-/_/g')
或者
branch=$(shell git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/' -e 's/-/_/g')
6.在Makefile规则中的shell好像无法更改Makefile变量
7. 如果Makefile里的target 需要shell脚本,那么直接写上去的情况下,在执行make时,这些脚本的内容会输出到标准输出。想要隐藏的话就要用$(shell ……) 这种写法。另外遇到一个很棘手的问题:我在target中需要对一个命令的执行结果做判断,也就是判断$?的值,但是结果是莫名其妙,因为$?被make先解释了。所以要判断的命令还是尽量放在target之外先去执行吧。
8. rpm spec中的%files宏最后不要忘记记录需要安装的文件