分享

通用makefile是如何炼成的(II)

 TUBOSS 2014-09-02

上一次我们完成了圈地运动,顺利拍下一块叫做build的地块。今天,我们就要在上面立个牌坊


一般情况下,我们总会在makefile中加入一些产品信息。比如产品名称,版本号,以及产品的特性开关(宏),等等

直接在main.mk中添加相应的内容

  1. # main.mk  
  2. #  
  3. RM:=rm -f  
  4.   
  5. ## 定义产品信息  
  6. PRODUCT_VENDOR:=common-mk  
  7. PRODUCT  
  8. CXX:=g++_VERSION:=1.0  
  9. ## 定义产品功能的开关  
  10. OPTIONS:=-DENABLE_TALKING=1 -DPRODUCT_INFO=\"$(PRODUCT_VENDOR)-$(PRODUCT_VERSION)\"  
  11. CXXFLAGS:=-Wall $(OPTIONS)  
  12. ...  


为了有所显示,我们在修改一下hello.cpp, 将产品信息打印出来

  1. /* 
  2.  * hello.cpp 
  3.  
  4.  */  
  5.   
  6. #include "hello.h"  
  7. #include <stdio.h>  
  8.   
  9. void sayhello() {  
  10.     printf("Hello World!\n");  
  11.     printf("product info: %s\n", PRODUCT_INFO);  
  12. #if ENABLE_TALKING==1  
  13.     printf("product feature:%s\n""Talking is enabled");  
  14. #else  
  15.     printf("product feature:%s\n""Talking is disabled");  
  16. #endif  
  17. }  

现在编译之后,输出的内容就不是简单的hello world了,而是

Hello World!
product info: common-mk-1.0
product feature:Talking is enabled


牌坊是简单的立上了,不过不够漂亮。因为至少还存在下面一个不足:

1. 修改产品信息是必须直接修改main.mk. 而main.mk是很重要的,万一哪个傻敷敷的一不小心把其他内容也修改了,怎么办呢?

2. 如果有多个产品,那么每次编译A产品时必须将makefile改成A的产品信息,编译B产品时又要改成B的产品信息,不停地改,累都累死了


一言概之,就是要将产品信息从主makefile中解耦合出来。办法也是很简单的,继续圈地。将产品信息集中到products目录下,main.mk中直接include product.mk就可以将所需要的产品信息导入进来了。

  1. # main.mk  
  2. #  
  3.   
  4. RM:=rm -f  
  5.   
  6. ## 定义产品信息  
  7. include build/products/product.mk  
  8.   
  9. CXX:=g++  
  10. CXXFLAGS:=-Wall $(OPTIONS)  



然后,这里我们对产品信息再做个小的分类,分成vendor信息和特性开关两部分,于是products文件夹的内容就是下面这个样子的:

  1. # vendor.mk  
  2.   
  3. ## 定义产品信息  
  4. PRODUCT_VENDOR:=common-mk  
  5. PRODUCT_VERSION:=1.0  

  1. # features.mk  
  2.   
  3. ## 定义产品功能的开关  
  4. OPTIONS:=-DENABLE_TALKING=1 -DPRODUCT_INFO=\"$(PRODUCT_VENDOR)-$(PRODUCT_VERSION)\"  


很不错了,无论如何修改产品信息,反正都不用直接修改main.mk了。(大笑products修改的一小步,是通用型makefile的一大步啊,后面很多东西都是基于这个思想来的)


今天的工作基本可以收工了,在最后在留个鱼钩,build-specs.mk。只要愿意,可以通过定义变量PRODUCT_SPECS, 将该变量中指定的makefile加载进来,从而提供一种额外定制化产品信息的能力。

你可能会觉得奇怪,有必要吗?直接修改features.mk, vendor.mk不就好了吗。嗯,是的,就目前工程,不是必须的,但以后面对未来的多模块编译,就会用得着了。这一个修改,稍微有点未雨绸缪了(大笑不要怪我思想太超前了)

  1. # main.mk  
  2.   
  3. RM:=rm -f  
  4.   
  5. ## 定义产品信息。这里BUILD_SPECS设置为空,表示我们不做额外定制化  
  6. PRODUCT_SPECS :=build/spec.mk  
  7. include build/products/product.mk  
  1. # product.mk  
  2.   
  3. ## vendor,version等产品信息定义在vendor.mk  
  4. include build/products/vendor.mk  
  5.   
  6. ## 各种特性开关定义在features.mk  
  7. include build/products/features.mk  
  8.   
  9. ## 加载额外定制的产品配置mk  
  10. include build/products/product-specs.mk  

  1. # product-specs.mk  
  2.   
  3. ## 逐个加载PRODUCT_SPECS指定的mk文。提供一种可定制化产品信息的方法  
  4. $(foreach specfile, $(PRODUCT_SPECS), $(eval -include $(specfile)))  



至此,我们成功地实现了在makefile中添加产品信息,以及如何将产品信息与主makefile解耦

今天的工作到此为止。



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多