表4. 组件名称和缺省值
名称缺省值Source_Files缺省为目录下拥有以下后缀的文件:cpp、cxx、cc、c和C。Header_Files缺省为目录下拥有以下后缀的文件:h、hpp、hxx和hh。Inline_Files缺省为目录下拥有以下后缀的文件:i和inl。Template_Files缺省为目录下以如下结尾的文件:_T.cpp、_T.cxx、_T.cc、_T.c和_T.C。Documentation_Files缺省为目录下满足如下条件的文件:README、readme、.doc、.html和.txt。Resource_Files缺省为目录下匹配项目名称并以rc作为后缀的文件。如果某个组件未在mpc文件中列出,则使用其缺省值。为了防止可能在目录中出现的一组文件被作为缺省值使用,用户应该为相应的组件定义一个空的集合。每个组件名称均有两种格式,第一种格式只是简单的在结构中使用一系列文件来表示:Source_Files {file1.cppfile2.cpp}第二种格式是一系列命名块的组合:Source_Files(MACRO_NAME) {BlockA {file1.cppfile2.cpp}BlockB {file3.cppfile4.cpp}}第二种格式允许用户在逻辑上将文件进行分组,以便将来能够更容易的进行维护。使用这种格式同样会对em3、gnuace、vc6、vc7、vc71和vc8的项目类型产生影响。如果某个在Source_Files中列出的源文件有相应的头文件或者内联文件同时存在于目录中,并且该文件并没有在相应的组件列表中列出,则该会自动添加到相应的组件列表中去。3.2.2.5 verbatim语句verbatim结构可以用来指定需要原样放置到生成的项目文件中去的内容。语法如下:vertabim(<project type>, <location>) {..}当MPC在生成由<project type>指定的项目类型,并且在模板文件中遇到匹配<location>名称指定的占位符(原文marker)时,将会直接使用块中的内容对去进行替换。如果在块中的空白需要被保留,在块中的每一行都应该使用双引号来把内容括起来。如,下面的例子描述了在生成的gnuace项目类型的GNUmakefile文件末尾,所有的all:目标都应该依赖foo。verbatim(gnuace, bottom) {all: foo}3.2.2.6 specific语句specific关键字可以用来为特定的项目类型定义特殊的赋值语句。该关键字允许为项目指定平台相关或者OS相关的值。例如,当你想在其中一些平台中链接qt-mt库,而在其他平台连接qt-mt230nc库时,可以使用如下的例子:specific(bmake, nmake, vc6, vc7, vc71, vc8) {lit_libs += qt-mt230nc} else {lit_libs += qt-mt}其中else语句必须与后花括号在同一行中出现(如果有的话)。对某一种项目类型使用非操作(使用“!”)将会导致块中的内容被应用到除该项目类型之外的其他项目类型。如果出现在specific语句中的某个关键字并不是MPC关键字,则该关键字将被作为模板值修饰符来解释。在这种情况下,该块的作用同-value_template命令行选项一样。3.2.2.7 conditional语句conditional块允许为特定的项目类型添加额外的源文件。语法如下:conditional(<project type> [, <project type> …]) {source1.cpp…}conditional(<project type> [, <project type> …]) {source1.cpp…} else {source2.cpp…}其中else语句必须与后花括号在同一行中出现(如果有的话)。对某一种项目类型使用非操作(使用“!”)将会导致块中的内容被应用到除该项目类型之外的其他项目类型。3.2.2.8 自定义类型和生成规则MPC允许用户根据需要自定义文件类型来支持自定义的生成规则。例如:project {Define_Custom(MOC) {automatic = 0command = $(QTDIR)/bin/mocoutput_option = -oinputext = .hpre_extension = _mocsource_outputext = .cppkeyword mocflags = commandflags}// Custom ComponentMOC_Files {QtReactor.h}Source_Files {QtReactor_moc.cpp}}上面的例子定义了一个名为“MOC”的自定义文件类型,其中描述了如何处理输入文件以及如何生成相应的输出文件,一旦该自定义文件类型被定义,用户可以使用MOC_Files来为该新文件类型指定输入文件。表5中列出了可以在Define_Custom块中使用的关键字。表5. Define_Custom关键字
关键字描述automatic如果设置为1,则会尝试为自定义类型搜索满足条件的文件并进行添加;如果设置为0,则不进行自动添加。command用来处理自定义类型的输入文件的命令。commandflags任何需要传递给命令的选项。dependent如果有值,则在所有生成的文件中都会根据值来添加依赖项,缺省值是没有任何值。inputext这是能够由该命令处理的用逗号分隔的输入文件扩展名列表。keyword <name>该关键字允许用户映射<name>到项目级别的命名空间,设置到该结构的值必须是可以在Define_Custom语句中使用的关键字之一,使用该关键字的作用是修改通常只能在自定义组件中使用的关键字的值(如:command、commandflags等)。libpath如果该命令需要一个不在通常的库搜索路径中出现的路径,该关键字可以用来保证命令能够找到在运行时需要的库。output_option如果命令能够指定单一的输出文件名,则应该进行指定;否则,应该对其进行忽略。pch_postrule如果设置为1,则会在自定义规则中添加一条规则,该规则将会修改源输出文件来包含相应的预编译头文件。postcommand该命令允许用户在主命令处理完成自定义的输入文件之后,运行指定的命令。pre_extension如果该命令生成多个拥有相同扩展名的文件,该命令可以用来在逗号分隔的列表中对其进行指定。例如,tao_idl分别为不同的扩展名生成两种类型的文件(C.h、S.h、C.cpp和S.cpp)。该关键字影响所有的扩展类型。source_pre_extension该关键字功能同pre_extension,但是只影响source_outputext。inline_pre_extension该关键字功能同pre_extension,但是只影响inline_outputext。header_pre_extension该关键字功能同pre_extension,但是只影响header_outputext。template_pre_extension该关键字功能同pre_extension,但是只影响template_outputext。resource_pre_extension该关键字功能同pre_extension,但是只影响resource_outputext。documentation_pre_extension该关键字功能同pre_extension,但是只影响documentation_outputext。pre_filename该关键字语法同pre_extension,不同之处在于是添加到文件名前面,而不是后面。该关键字影响所有的扩展类型。source_pre_filename该关键字功能同pre_filename,但是只影响source_outputext。inline_pre_filename该关键字功能同pre_filename,但是只影响inline_outputext。header_pre_filename该关键字功能同pre_filename,但是只影响header_outputext。template_pre_filename该关键字功能同pre_filename,但是只影响template_outputext。resource_pre_filename该关键字功能同pre_filename,但是只影响resource_outputext。documentation_pre_filename该关键字功能同pre_filename,但是只影响documentation_outputext。source_outputext该关键字包含由逗号分隔的一系列可能的输出源文件扩展名,如果该命令不生成源文件,则不需要使用该关键字。inline_outputext该关键字包含由逗号分隔的一系列可能的输出内联文件扩展名,如果该命令不生成内联文件,则不需要使用该关键字。header_outputext该关键字包含由逗号分隔的一系列可能的输出头文件扩展名,如果该命令不生成头文件,则不需要使用该关键字。template_outputext该关键字包含由逗号分隔的一系列可能的输出模板文件扩展名,如果该命令不生成模板文件,则不需要使用该关键字。resource_outputext该关键字包含由逗号分隔的一系列可能的输出资源文件扩展名,如果该命令不生成资源文件,则不需要使用该关键字。documentation_outputext该关键字包含由逗号分隔的一系列可能的输出文档文件扩展名,如果该命令不生成文档文件,则不需要使用该关键字。generic_outputext如果该命令不生成前面列出的文件类型,那么在这里指定这些扩展名。在自定义组件和源文件组件、头文件组件和内联文件组件之间有特殊的交互作用:如果一个custom定义被设置为“automatic”,并且自定义组件文件存在却没有直接指明,除非这些名字已经在这些组件中列出(或者部分列出),否则缺省行为将自动将这些生成的文件名自动添加到相应的源文件组件、头文件组件和内联文件组件列表中去。针对自定义生成类型的个别输出扩展名并不是必须的。但是,至少需要指定一个输出扩展类型来告诉MPC如果生成目标。另一方面,使用的命令并不一定要生成输出,但是如果你想要你的输入文件能够在项目编译时被处理,则必须要指定一种扩展类型。如果自定义输出类型不能在上面列出的扩展类型关键字(*_outputext)中列出,但是你能够预先知道输出文件名称,则可以用“>>”构造块来列出。下面是一个展示如何使用“>>”构造块的例子,在该例子中,该命令使用一个输入文件foo.prp,并生成两个没有任何关联的输出文件:hello.h和hello.cpp。project {Define_Custom {automatic = 0command = perl quogen.plcommandflags = --debuglevel=1 --language=c++ \ --kernel_language=c++inputext = .cppkeyword quogenflags = commandflags}Quogen_Files {foo.prp >> hello.h hello.cpp}Source_Files {hello.cpp}}你可以使用“<<”结构在表示特定的自定义输入文件的依赖关系。例如,在上面的例子中,假定输入文件foo.prp依赖于foo.in,则我们可以通过“<<”来像下面例子一样的来对foo.in进行指定。Quogen_Files {foo.prp >> hello.h hello.cpp << foo.in}在Custom_Build块中,还可以使用optional结构,该结构用来在当特定的输出文件依赖于特定的可选命令行参数时,对其进行指定。project {Define_Custom(TEST) {optional(keyword) {flag_keyword(option) += value [, value]}}}在上面的片段中,keyword可以是任何形式的pre_extension、pre_filename或者是以_outputext结尾的关键字。flag_keyword可以是任何的自定义组件关键字(尽管只有commandflags有功能性的值),MPC会在在flag_keyword的值中搜索括号中的option值,如果有,则在+=后的value或者values将会被添加到keyword指定的列表中去,可以使用非操作(使用“!”)来达到相反的效果。下面的例子optional结构是如何使用来影响tao_idl命令的自定义定义的(参见:ACE_wrappers/bin/MakeProjectCreator/config/taoidldefaults.mpb)。其中的-GA命令行选项将导致tao_idl基于idl文件的文件名生成额外的使用A.cpp扩展的源文件,-Sc命令行选项将导致tao_idl不生成与S_T有关的文件。Define_Custom(IDL) {…inputext = .idlsource_pre_extension = C, Sheader_pre_extension = C, Sinline_pre_extension = C, Ssource_outputext = .cpp, .cxx, .c, .Cheader_outputext = .h, .hpp, .hxx, .hhinline_outputext = .inl, .ikeyword idlflags = commandflagsoptional(source_pre_extension) {commandflags(-GA) += A}optional(template_outputext) {commandflags(!-Sc) += S_T.cpp, S_T.cxx, S_T.cc, S_T.C}optional(header_pre_extension) {commandflags(!-Sc) += S_T}optional(inline_pre_extension) {commandflags(!-Sc) += S_T}}对于自定义文件类型,只有如下的的关键字可以在自定义文件类型组件列表中使用:command、commandflags、dependent、gendir、postcommand和recurse。其中:recurse关键字作用同赋值关键字中的相同;command、commandflags、dependent和postcommand可以用来增加或覆盖在Define_Custom节中的设置;gendir关键字用来指定存放输出文件的目录(只有在Define_Custom中设置了output_option时才起作用),例如:MOC_Files {commandflags += -nwgendir = moc_generatedQtReactor.h}Source_Files {moc_generated/QtReactor_moc.cpp}在上面的例子中,-nw命令行选项被添加到commandflags值中,并且输出文件(QtReactor_moc.cpp)被存放到moc_generated目录。如果MOC自定义组件并没有设置output_option,则命令行选项没必要添加到commandflags值中去,同时需要使用postcommand来保证输出文件被存放到moc_generated目录。