Why
在使用Jam建立目标依赖的过程中,有时需要根据source的内容动态建立依赖,例如一个c/c++的源文件,一般#include其他文件,我们需要把#include也作为source加入到依赖里,这样的好处很明显,就是当头文件更新了我们也可以自动build target,并且不需要手动建立和维护这些对头文件的依赖。
How
Jam中有关header file searching的变量一共4个,分别是
- HDRSCAN - 一个egrep pattern,用于对文件进行按行search时使用,该patttern的第一个group的返回值作为source,将会被传递给HDRRULE
- HDRRULE - 当根据HDRSCAN找到一个依赖时,将会以$(HDRRULE) TARGET : SOURCE 的形式来调用
- HDRGRIST - 由HDRRULE使用,用来grist一个target
- HDRSEARCH – 指定搜索的source的搜索目录,类似于HDRS, STDHDRS
要让header file scanning在一个target上起作用,必须同时在这个target上设置HDRSCAN和HDRRULE这两个变量。最好不要设置这两个变量为全局变量,因为这样所有的target都会进行scanning。
我们来看一个例子,假定我们需要编译一个资源,这个资源文件里,会以INCLUDES "XXX"的形式包含其他的源文件,而我们需要找到XXX,并且建立这个依赖。
HDRSCAN
使用egrep的语法,就是HDRSCAN就应该是 INCLUDES[tab-space]+"(.+)",这里tab和space就是你对应的输入的字符,这里为了清楚而替代以文字表示。
Activate Scanning
激活header file scanning,必须设置2个变量HDRSCAN和HDRRULE
HDRSCAN on $(SOURCE) = "INCLUDES[ ]+/"(.+)/"" ; HDRRULE on $(SOURCE) = CustomHDRRule ; HDRGRIST on $(SOURCE) = $(SOURCE_GRIST:E=) ; HDRSEARCH on $(SOURCE) = $(SEARCH_SOURCE) ;
CustomHDRRule是我们的HdrRule,用来建立target和source的依赖。
这里我们只针对.rc的资源文件进行扫描,来看一下完整的Jamfilerule CustomHDRRule TARGET : SOURCE { Includes $(TARGET) : $(SOURCE) ; SEARCH on $(SOURCE) = $(HDRSEARCH) ; NoCare $(SOURCE) ; if $(SOURCE:S) = .rc { HDRSCAN on $(SOURCE) = $(HDRSCAN) ; HDRRULE on $(SOURCE) = $(HDRRULE) ; HDRGIRST on $(SOURCE) = $(HDRGRIST) ; HDRSEARCH on $(SOURCE) = $(HDRSEARCH) ; } }
这里编译test.rc文件为test,会扫描test.rc的内容,动态建立依赖。SubDir TOP ; rule CustomHDRRule TARGET : SOURCE { Includes $(TARGET) : $(SOURCE) ; SEARCH on $(SOURCE) = $(HDRSEARCH) ; NoCare $(SOURCE) ; if $(SOURCE:S) = .rc { HDRSCAN on $(SOURCE) = $(HDRSCAN) ; HDRRULE on $(SOURCE) = $(HDRRULE) ; HDRGIRST on $(SOURCE) = $(HDRGRIST) ; HDRSEARCH on $(SOURCE) = $(HDRSEARCH) ; } } rule CompileRes PARENT : TARGET : SOURCE { if ! $(TARGET) { TARGET = $(SOURCE:S=) ; } TARGET = [ FGristFiles $(TARGET) ] ; SOURCE = [ FGristFiles $(SOURCE) ] ; Depends $(PARENT) : $(TARGET) ; Depends $(TARGET) : $(SOURCE) ; CompileRes_ $(TARGET) : $(SOURCE) ; Clean clean : $(TARGET) ; HDRSCAN on $(SOURCE) = "INCLUDES[ ]+/"(.+)/"" ; HDRRULE on $(SOURCE) = CustomHDRRule ; HDRGRIST on $(SOURCE) = $(SOURCE_GRIST:E=) ; HDRSEARCH on $(SOURCE) = $(SEARCH_SOURCE) ; } actions CompileRes_ { cp $(>) $(<) } CompileRes all : : test.rc ;
下面是工程的源文件,有兴趣可以下载尝试一下。下载后把扩展名改为tar即可解压。