找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4256|回复: 0

MPC使用介绍(四)

[复制链接]
发表于 2008-4-22 16:18:33 | 显示全部楼层 |阅读模式
下面的内容紧接着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_filessource_filesheader_files列表中的每一个值。如果foreach的第一个变量并不以“s”字符结尾,则使用同第一个变量名相同的名称来表示。如:

<%foreach(filelist)%> <% filelist%><%endfor%>

表8中列出了可以在模板文件中使用的关键字。
表8. 模板文件关键字
关键字描述
if用来决定某个变量是否被定义。非操作(!)可以用来反转结果。该结构只检查在mpc文件或mpt文件中出现的值定义,缺省值(即使是由项目创建器实现的)并不会被if语句考虑。
elseif语句一起使用,只有当if语句不为真的时候,else语句才会被执行。
endifif语句一起使用,用来结束if或者if/else块。
noextension将变量值解释为文件名,并从变量中移除扩展名以及表示扩展名的点号。
dirname将变量值解释为文件名,并从变量中移除basename
basename将变量值解释为文件名,并从变量中移除目录信息。
basenoextension作用类似basename,不过同时从变量中移除扩展名以及表示扩展名的点号。
foreach在空格分隔的列表环境中计算变量。
forfirstforeach一起使用,传递给forfirst的文字值会被放置到foreach中第一个迭代中去。
fornotfirstforeach一起使用,传递给fornotfirst的文字值会被放置到foreach中除第一个之外的每一个迭代中去。
forlastforeach一起使用,传递给forlast的文字值会被放置到foreach中最后一个迭代中去。
fornotlastforeach一起使用,传递给fornotlast的文字值会被放置到foreach中除最后一个之外的每一个迭代中去。
endforforeach一起使用,用来结束foreach块。
comment传递给comment的任何值都将被忽略(注释),可以使用任何除去换行和语句结束符之外的任何字符。
flag_overrides直接覆盖在mpc文件中的项目范围内的设置,使用两个由逗号分隔的变量,第一个变量对应一个文件名,第二个可以是任何变量。
marker同mpc语法中的verbatim关键字,可以用来在模板中指定占位符。如,<%marker(local)%>
uc返回变量值的大写字母形式。
lc返回变量值的小写字母形式。
ucw返回变量值中每个单词首字母大写的形式,单词使用空格或者下划线来进行分隔。
normalize将连字号、斜杠、美元符号、括号以及点号转换为下划线。
reverse反转数组参数值的顺序。
sort对数组参数值进行排序。
uniq返回数组参数值的唯一集合。
multiple如果数组参数包含多个值,则返回真。
starts_with如果参数值(第一个参数)以给出的正则表达式(第二个参数)开始,则返回真。
ends_with如果参数值(第一个参数)以给出的正则表达式(第二个参数)结尾,则返回真。
contains如果参数值(第一个参数)匹配给出的正则表达式(第二个参数),则返回真。

表9中列出了在部分模板文件中可以作为参数的一些特殊名称。在表7中列出的变量也可以使用(除了<%temporary%>)。
表9. 可在模板文件中使用的特殊值
描述
custom_types包含自定义生成类型的列表。更多信息参见自定义类型。
cwd完整的当前工作目录。
forcount仅可与foreach一起使用,表示从1开始计数的foreach元素索引。
project_name包含了当前正在被处理的项目名称。
project_file包含了当前正在被处理的项目的输出文件名。
ciao在GNUACE项目创建器模块中实现,指定项目使用了CIAO。
cppdir在BMake项目创建器模块中实现,返回由分号分隔的Source_Files列表值。
rcdir在BMake项目创建器模块中实现,返回由分号分隔的Resource_Files列表值。
make_file_name在VC6和EM3项目创建器模块中实现,返回对应到该特定项目类型的由项目名称与make文件扩展组合在一起的文件名。
tao在GNUACE项目创建器模块中实现,指定项目使用了TAO。
guid在VC7项目创建器模块中实现,返回一个在VC7项目文件中使用的基于项目的guid值。
vcversion在VC7项目创建器模块中实现,返回被创建项目类型的版本号:vc7返回7.00,vc71返回7.10,vc8返回8.00。
vpath在GNUACE项目创建器模块中实现,返回源文件相对于在GNU Make中的VPATH设置的路径值。

4.1.1.1 自定义类型
为了支持多个自定义生成类型,我们使用了一个特殊的关键词。custom_types关键词用来访问一系列的用户自定义类型。在foreach循环中,可以使用custom_type关键词来访问每一个自定义类型。
通过对custom_type关键词使用->操作符,我们可以访问一些常用的信息:输入文件、输入文件扩展名、命令、命令输出选项、命令标志以及输出文件目录,这些信息可以通过对应该类型的字段名来进行访问。同该自定义类型相关的输入文件可以使用custom_type->input_files来进行访问,每一个输入文件都会对应以系列的输出文件,这些输出文件可以在foreach循环中通过custom_type->input_file->output_files来访问。表10中列出了自定义类型字段。
表10. 自定义类型字段
描述
command自定义类型中使用的命令。
commandflags不包括输出选项的命令行选项。
dependent告诉命令哪些生成的文件需要有依赖。
gendir针对特定文件类型的输出目录,该字段直接通过custom_type来访问则没有任何意义,应该始终在flag_overrides上下文中使用。
input_files与自定义类型关联的输入文件。
inputexts与自定义类型关联的输入文件扩展名。
libpath命令相关的库路径设置。
output_option可选的命令输出选项。
pch_postrule用来决定命令是否需要支持预编译头。
postcommand该命令允许用户在主命令处理完成自定义的输入文件之后,运行指定的命令。

例如,在下面的例子中,为生成自定义的输入文件创建了一个通用的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_FilesHeader_Files)可以按照组件小节中介绍的第二种方式来群组到一起。在mpd文件中,不同的组件可以通过在前面加上grouped_前缀来进行访问(如:grouped_source_filesgrouped_header_files等)。
表11. 群组文件字段名
字段名描述
files组中的输入文件。
component_name群组文件的组名。

下面是一个如何针对每一个组创建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范围类可用。


[ 本帖最后由 earthdog 于 2008-4-22 16:50 编辑 ]
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-7 06:34 , Processed in 0.018186 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表