MPC使用介绍(四)
下面的内容紧接着MPC使用介绍(一)、MPC使用介绍(二)和MPC使用介绍(三)。 4. 增加新类型 如果MPC并不支持某个特定的生成工具,你可能会考虑为其增加一个新的项目类型。例如,我们可以为MPC添加对Boost Jam、Eclipse、Xcode以及其他很多类型生成工具的支持。要达到这样的要求,我们需要有关于MPC输入文件以及面向对象Perl的知识。 4.1 输入文件语法 在这一节中,我们将为大家介绍在项目生成是使用的输入文件语法: 4.1.1 模板文件(mpd) 模板文件由大量MPC放入到每个生成的项目文件中去的信息构成,这些文件通过不同的模板指令来根据mpc文件的内容来提供相应的文本和数据的布局。 模板指令由<%%>结构来进行声明,该结构用来提供if语句、foo循环以及变量访问功能,需要注意的是,所有没有被<%%>包围的文本,包括空白都会原封不动的传递到生成的项目文件中去。 if语句可以只占用一行,也可以占用多行。例如,下面这行: <%if(exename)%>BIN = <%exename%><%else%>LIB = <%sharedname%><%endif%> 同下面几行是一样的: <%if(exename)%> BIN = <%exename%> <%else%> LIB = <%sharedname%> <%endif%> foreach语句同样可以占用一行或者多行,如同关键字小节中描述的,foreach语句在空格分隔的列表环境中计算变量。foreach循环可以采用多种书写方式,第一种方式是对循环变量进行命名并列出每个变量值,这也是比较推荐的做法: FILES=<%foreach(fvar, idl_files source_files header_files)%> <%fvar%><%endfor%> 第二种方式是让foreach来决定变量名称,在这种方式中,每个值都可以用传递给foreach的第一个变量的变量名称去除掉结尾的“s”字符来访问: FILES=<%foreach(idl_files source_files header_files)%> <%idl_file%><%endfor%> 需要注意的是,<%idl_file%>变量会循环迭代idl_files、source_files和header_files列表中的每一个值。如果foreach的第一个变量并不以“s”字符结尾,则使用同第一个变量名相同的名称来表示。如: <%foreach(filelist)%> <% filelist%><%endfor%> 表8中列出了可以在模板文件中使用的关键字。 表8. 模板文件关键字
表9中列出了在部分模板文件中可以作为参数的一些特殊名称。在表7中列出的变量也可以使用(除了<%temporary%>)。 表9. 可在模板文件中使用的特殊值
4.1.1.1 自定义类型 为了支持多个自定义生成类型,我们使用了一个特殊的关键词。custom_types关键词用来访问一系列的用户自定义类型。在foreach循环中,可以使用custom_type关键词来访问每一个自定义类型。 通过对custom_type关键词使用->操作符,我们可以访问一些常用的信息:输入文件、输入文件扩展名、命令、命令输出选项、命令标志以及输出文件目录,这些信息可以通过对应该类型的字段名来进行访问。同该自定义类型相关的输入文件可以使用custom_type->input_files来进行访问,每一个输入文件都会对应以系列的输出文件,这些输出文件可以在foreach循环中通过custom_type->input_file->output_files来访问。表10中列出了自定义类型字段。 表10. 自定义类型字段
例如,在下面的例子中,为生成自定义的输入文件创建了一个通用的makefile规则,显示了自定义类型的基本用法以及可以访问的一些字段,使用custom_types关键词的一个主要局限(可以在下面的例子中看到)就是不能为foreach指定别的变量名。 <%if(custom_types)%> <%foreach(custom_types)%> <%foreach(custom_type->input_files)%> <%foreach(custom_type->input_file->output_files)%> <%custom_type->input_file_output_file%>: <%custom_type->input_file%> <%custom_type->command%> <%custom_type->commandflags%> $@ <%endfor%> <%endfor%> <%endfor%> <%endif%> 4.1.1.2 群组文件 mpc文件语法中支持文件群组:可以在一个mpc文件中将一系列文件作为群组并在mpd文件中作为一个整体来进行访问。 文件(例如:Source_Files、Header_Files)可以按照组件小节中介绍的第二种方式来群组到一起。在mpd文件中,不同的组件可以通过在前面加上grouped_前缀来进行访问(如:grouped_source_files、grouped_header_files等)。 表11. 群组文件字段名
下面是一个如何针对每一个组创建make宏的例子,展示了群组的基本用法和如何对字段进行访问。使用文件群组功能的主要局限(可以在下面的例子中看到)就是不能为foreach指定别的变量名。下面的例子中只使用了源文件,但是所有在mpc和mpd小节中列出的组件均可以使用。 <%if(grouped_source_files)%> <%comment(Get back each set of grouped files)%> <%foreach(grouped_source_files)%> <%comment(This will provide the name of the group)%> <%grouped_source_file%> = / <%comment(Get all the source files in a single group)%> <%foreach(grouped_source_file->files)%> <%grouped_source_file->file)%><%fornotlast(“ //”)%> <%endfor%> <%endfor%> ifndef <%grouped_source_files->component_name%> <%grouped_source_files->component_name%> = / <%foreach(grouped_source_files)%> <%grouped_source_file%><%fornotlast(“ //”)%> <%endfor%> endif <%endif%> 4.1.2 模板输入文件(mpt) 模板输入文件对于所有项目来说都通用的编译工具相关的特定信息。例如:编译器开关、中间文件目录、编译器宏等。每一个项目类型均可以为动态库、静态库、动态可执行文件和静态可执行文件提供相应的模板输入文件。但是,所有这些都不被MPC所实际需要。 模板输入文件相对于其他的MPC文件类型来说格式更加自由。它的语法类型mpc文件的语法,区别在于没有项目定义,并且只能使用一个关键词:conditional_include。该关键词用来包含其他可以在MPC包含文件搜索路径中找到的mpt文件,如果在conditional_include关键词后用双引号引起的名称没有找到,则忽略该名称,并且不会有任何的警告提示。mpt后缀会被自动添加到提供的名称后。 模板输入文件包含一系列的变量赋值操作。该变量赋值操作可以是下面两种方式中的任何一种: variable_name = value1 “value 2” variable_name += another_value 这些变量可以在对于的mpd文件中进行使用。 在一个mpt文件中,变量赋值操作可以组合到一起并进行命名,并在mpd文件中作为范围变量来进行使用。下面的例子显示了变量赋值组合使用的方式: // mpt file configurations = Release Debug common_defines = WIN32 _CONSOLE Release { compiler_flags = /W3 /GX /O2 /MD /GR defines = NDEBUG } Debug { compiler_flags = /W3 /Gm /GX /Zi /Od /MDd /GR /Gy defines = _DEBUG } conditional_include “vcfullmacros” 下面mpd文件片段使用了上面的mpt文件所提供的信息: <%foreach(configurations)%> Name = <%configuration%> <%compile_flags%><%foreach(defines common_defines)%> /D <%define%>=1<%endfor%> <%endfor%> 下面的内容则显示了上面例子的输出结果: Name = Release /W3 /GX /O2 /MD /GR /D NDEBUG=1 /D WIN32=1 /D _CONSOLE=1 Name = Debug /W3 /Gm /GX /Zi /Od /MDd /GR /Gy /D _DEBUG=1 /D WIN32=1 /D _CONSOLE=1 如果一个foreach变量对应一个变量组名,则该变量组在该foreach范围类可用 |