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

上一次我們完成了圈地運動,順利拍下一塊叫做build的地塊。今天,我們就要在上面立個牌坊


一般情況下,我們總會在makefile中加入一些產品信息。比如產品名稱,版本號,以及產品的特性開關(宏),等等

直接在main.mk中添加相應的內容

# main.mk
#
RM:=rm -f

## 定義產品信息
PRODUCT_VENDOR:=common-mk
PRODUCT
CXX:=g++_VERSION:=1.0
## 定義產品功能的開關
OPTIONS:=-DENABLE_TALKING=1 -DPRODUCT_INFO=\"$(PRODUCT_VENDOR)-$(PRODUCT_VERSION)\"
CXXFLAGS:=-Wall $(OPTIONS)
...


爲了有所顯示,我們在修改一下hello.cpp, 將產品信息打印出來

/*
 * hello.cpp

 */

#include "hello.h"
#include <stdio.h>

void sayhello() {
	printf("Hello World!\n");
	printf("product info: %s\n", PRODUCT_INFO);
#if ENABLE_TALKING==1
	printf("product feature:%s\n", "Talking is enabled");
#else
	printf("product feature:%s\n", "Talking is disabled");
#endif
}

現在編譯之後,輸出的內容就不是簡單的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就可以將所需要的產品信息導入進來了。

# main.mk
#

RM:=rm -f

## 定義產品信息
include build/products/product.mk

CXX:=g++
CXXFLAGS:=-Wall $(OPTIONS)



然後,這裏我們對產品信息再做個小的分類,分成vendor信息和特性開關兩部分,於是products文件夾的內容就是下面這個樣子的:

# vendor.mk

## 定義產品信息
PRODUCT_VENDOR:=common-mk
PRODUCT_VERSION:=1.0

# features.mk

## 定義產品功能的開關
OPTIONS:=-DENABLE_TALKING=1 -DPRODUCT_INFO=\"$(PRODUCT_VENDOR)-$(PRODUCT_VERSION)\"


很不錯了,無論如何修改產品信息,反正都不用直接修改main.mk了。(大笑products修改的一小步,是通用型makefile的一大步啊,後面很多東西都是基於這個思想來的)


今天的工作基本可以收工了,在最後在留個魚鉤,build-specs.mk。只要願意,可以通過定義變量PRODUCT_SPECS, 將該變量中指定的makefile加載進來,從而提供一種額外定製化產品信息的能力。

你可能會覺得奇怪,有必要嗎?直接修改features.mk, vendor.mk不就好了嗎。嗯,是的,就目前工程,不是必須的,但以後面對未來的多模塊編譯,就會用得着了。這一個修改,稍微有點未雨綢繆了(大笑不要怪我思想太超前了)

# main.mk

RM:=rm -f

## 定義產品信息。這裏BUILD_SPECS設置爲空,表示我們不做額外定製化
PRODUCT_SPECS :=build/spec.mk
include build/products/product.mk
# product.mk

## vendor,version等產品信息定義在vendor.mk
include build/products/vendor.mk

## 各種特性開關定義在features.mk
include build/products/features.mk

## 加載額外定製的產品配置mk
include build/products/product-specs.mk


# product-specs.mk

## 逐個加載PRODUCT_SPECS指定的mk文。提供一種可定製化產品信息的方法
$(foreach specfile, $(PRODUCT_SPECS), $(eval -include $(specfile)))



至此,我們成功地實現了在makefile中添加產品信息,以及如何將產品信息與主makefile解耦

今天的工作到此爲止。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章