Makefile的小妙用

 
  做过Linux平台下开发工作的同学肯定对GNU Make工具再熟悉不过了,通过编写Makefile可以建立项目各部分目标的依赖关系,同时make工具自动跟踪源代码修改操作,所以之后程序员在进行任意源代码修改之后只需一个make命令,整个项目就可以根据修改和依赖关系进行最小化生成操作,并最终正确生成最终目标了。这一切都那么的自然,自然的不在话下。
  最近公司一位大佬分享交易对账课题,对于交易和支付公司而言对账事务是每天逃不过的日经工作了,这种重复性的体力活动自然是自动化程度越高越好了,而且对账这个东西虽说事情很简单,但是涉及到的工作很多:提取本地数据、抓取下游数据、两端数据对比生成结果、数据统计和发送,这个过程中,不同合作伙伴的通道的接口千奇百怪的,对账文件的格式也是千差万别,而且退票、重打款、或者业务对订单的修改等操作可能还需要重新再对账,整个过程甚是繁琐。
  针对这个问题,大家通常都是将各个渠道、各个功能编码成对应的模块,然后在主脚本中依次调用这些模块做个批次化的操作,当需要重新执行某项操作的时候,手动执行对应模块就可以了。为了提高效率,避免重复操作,这个过程中还会引入一些状态的记录,比如哪些数据已经同步了,哪些数据已经从远端服务器下载了,哪些数据需要强制刷新重获取。对于状态标记最直观的方式就是通过数据库插入和更新记录的方式,但是需要刷新某些记录的时候需要手动修改数据库,对于每天需要大量查库的人来说已经比较反感这种方式了,麻烦不说还比较容易出错;其实如果目标是下载文件,那么完全可以在脚本中检查对应文件是否存在而决定是否执行更新操作了,而对于需要强制更新的话,则可以手动删除目标文件就可以了,不过有的时候目标的文件会比较多也比较杂乱,或者目标不体现在文件系统上面,那么此时你可以自己在文件系统中创建某个虚拟目标文件来做状态记录使用就可以了,其实到了这里的话,离本文的目标主旨已经近了一大步了。
  上面说到的虚拟目标文件的方式已经比较灵活了,但是整个操作还是批次化的流水操作,每次更新都需要将流程走一遍,不能智能地解决复杂的依赖关系;还有如果要产生定制化的操作,要么需要对脚本传入参数进行控制,要么产生各种需求的脚本文件,需求多了的话管理起来就会比较麻烦!
  然后,这次培训分享会上,同事带来的使用Makefile方式解决这种依赖关系的点子着实不错。首先Makefile对于简单的、或者各种层次复杂的依赖关系都能很好的处理,毕竟他天生就是干这货的;其次,一个Makefile中可以有多个最终目标存在,这就意味着执行make的时候只需要对同一个Makefile传递不同的目标参数,就可以得到不同的执行效果,而且这些目标共存在同一个Makefile文件中,彼此可以共享某些目标,而且他们本身也可以形成层次的目标关系;Makefile文件天然和shell具有强烈的亲和关系,在Makefile中执行各类shell语句完成业务逻辑十分方便。实现起来就不细谈了,目标文件可以自动生成,如果是虚拟目标的话,在成功执行后最后记得touch一个目标文件就可以了。
  总结来说,其实这个东西一点出来大家都知道,原理大家也都心知肚明,但是就是感觉很多程序员的思维比较的僵硬和局限(至少我是比较这样的吧),各种开发工具完的很溜、各种原理和实现滚瓜烂熟甚至是专家级别,但常常只是被束缚在其常用的领域和层面上。工具是术,如果能够“以术得道”看清问题的本质,在各种环境和需求下灵活运用,才能算作是真正的驾驭工具,服务我们工作和生活的方方面面。
  好了,说到这里,想想生活和工作中还有哪些地方可以用上Makefile?

本文完!