|
下面的内容紧接着MPC使用介绍(一)、MPC使用介绍(二)、MPC使用介绍(三)和MPC使用介绍(四)。
4.2 一个简单的例子
在这个小节,我们将通过为一个虚构的生成工具添加支持来讨论如何增加新的类型。图1描述了我们下面要讨论的模板和项目创建器之间的关系。
4.2.1 模板
最适合我们的讨论的方式是从模板开始讨论。模板是添加新的项目类型最重要的地方,它从基础上告诉MPC当处理mpc文件时,如何布置收集到的信息。模板文件是包含普通文本和mpd语法文本。下面是我们的例子文件:fictional.mpd。
//=======================================================================
// This project has been generated by MPC.
// CAUTION! Hand edit only if you know what you are doing!
//=======================================================================
// Section 1 - PROJECT OPTIONS
ctags:*
debugSwitches:-nw
//end-proj-opts
// Section 2 - MAKEFILE
Makefile.<%project_name%>
// Section 3 - OPTIONS
//end-options
// Section 4 - TARGET FILE
<%if(exename)%>
<%exename%>
<%else%>
<%if(sharedname)%>
<%sharedname%>
<%else%>
<%if(staticname)%>
<%staticname%>
<%endif%>
<%endif%>
<%endif%>
// Section 5 - SOURCE FILES
<%foreach(source_files)%>
<%source_file%>
<%endfor%>
//end-srcfiles
// Section 6 - INCLUDE DIRECTORIES
<%foreach(includes)%>
<%include%>
<%endfor%>
//end-include-dirs
// Section 7 - LIBRARY DIRECTORIES
<%foreach(libpaths)%>
<%libpath%>
<%endfor%>
//end-library-dirs
// Section 8 - DEFINITIONS
<%foreach(macros defines)%>
-D<%macro%>
<%endfor%>
<%if(pch_header)%>
<%foreach(pch_defines)%>
-D<%pch_define%>
<%endfor%>
<%endif%>
//end-defs-pool
// Section 9 - C FLAGS
<%cflags("-g")%>
// Section 10 - LIBRARY FLAGS
<%libflags%>
// Section 11 - SRC DIRECTORY
.
// Section 12 - OBJ DIRECTORY
<%objdir(".")%>
// Section 13 - BIN DIRECTORY
<%if(install)%><%install%><%else%>.<%endif%>
// User targets section. Following lines will be
// inserted into Makefile right after the generated cleanall target.
// The Project File editor does not edit these lines - edit the .vpj
// directly. You should know what you are doing.
// Section 14 - USER TARGETS
<%marker(top)%>
<%marker(macros)%>
<%marker(local)%>
<%marker(bottom)%>
//end-user-targets
// Section 15 - LIBRARY FILES
<%foreach(libs lit_libs pure_libs)%>
<%lib%>
<%endfor%>
//end-library-files
需要注意的是,根据<%exename%>、<%sharedname%>或者<%staticname%>是否被定义,我们生成了不同类型的输出文件;同样的,项目文件中的特殊部分只在某个特殊的变量被设置时才进行了生成。
4.2.2 项目创建器
下面,你需要做的是编写FictionalProjectCreator.pm文件。我们可以从MakeProjectCreator.pm文件中拷贝一份来进行编辑,首先是修改包名称为FictionalProjectCreator并从MakeProjectBase和ProjectCreator继承,然后覆盖在该类型中需要的方法。
package FictionalProjectCreator;
# ************************************************************
# Description : A Fictional Project Creator
# Author : Chad Elliott
# Create Date : 10/01/2004
# ************************************************************
# ************************************************************
# Pragmas
# ************************************************************
use strict;
use MakeProjectBase;
use ProjectCreator;
use vars qw(@ISA);
@ISA = qw(MakeProjectBase ProjectCreator);
# ************************************************************
# Subroutine Section
# ************************************************************
sub convert_slashes {
#my($self) = shift;
return 0;
}
sub project_file_extension {
#my($self) = shift;
return '.fic';
}
sub get_dll_exe_template_input_file {
#my($self) = shift;
return 'fictionalexe';
}
sub get_dll_template_input_file {
#my($self) = shift;
return 'fictionaldll';
}
sub get_template {
#my($self) = shift;
return 'fictional';
}
1;
在我们的例子中,我们继承了MakeProjectCreator,MakeProjectCreator提供了一些对于“所有”的基础项目创建器来说都是相同的方法。
我们覆盖了convert_slashes方法并返回了0,返回零值表示告诉MPC不要将正斜杠转换成反斜杠(这种转换对于Windows平台上的生成工具来说很有用)。
然后,我们覆盖了project_file_extension方法并返回项目文件的扩展名,该方法为MakeProjectBase模块中其他方法所使用。
接下来,我们覆盖了get_dll_exe_template_input_file和get_dll_template_input_file方法,这两个方法根据动态链接的可执行文件和动态库类型的不同返回特定的模板输入文件名。
最后,我们覆盖了get_template方法来为我们的新的项目类型返回模板文件名。在我们的例子中,该方法返回fictional,对应我们之前创建的模板文件的文件名。
同时,还有许多方法可以被覆盖来修改MPC生成输出文件的方法。参见“Creator.pm”和“ProjectCreator.pm”文件中的“可以被覆盖的虚方法”一节。
4.2.3 工作区创建器
接下来需要编写的就是FictionalWorkspaceCreator.pm文件了,该模块同项目创建器比较起来更加侧重在代码的变化上。
package FictionalWorkspaceCreator;
# ************************************************************
# Description : A Fictional Workspace Creator
# Author : Chad Elliott
# Create Date : 10/01/2004
# ************************************************************
# ************************************************************
# Pragmas
# ************************************************************
use strict;
use FictionalProjectCreator;
use WorkspaceCreator;
use vars qw(@ISA);
@ISA = qw(WorkspaceCreator);
# ************************************************************
# Subroutine Section
# ************************************************************
sub workspace_file_name {
my($self) = shift;
return $self->get_modified_workspace_name($self->get_workspace_name(), '.fws');
}
sub pre_workspace {
my($self) = shift;
my($fh) = shift;
my($crlf) = $self->crlf();
print $fh '<?xml version="1.0" encoding="UTF-8"?>', $crlf,
'<!-- MPC Command -->', $crlf,
"<!-- $0 @ARGV -->", $crlf;
}
sub write_comps {
my($self) = shift;
my($fh) = shift;
my($projects) = $self->get_projects();
my(@list) = $self->sort_dependencies($projects);
my($crlf) = $self->crlf();
print $fh '<projects>', $crlf;
foreach my $project (@list) {
print $fh " <project path=\"$project\"/>$crlf";
}
print $fh "</projects>$crlf";
}
1;
我们需要覆盖的从WorkspaceCreator.pm中继承过来的方法是workspace_file_name方法,该方法用来决定生成的工作区文件的文件名称。
接下来,我们覆盖了pre_workspace方法,我们用该方法来输出生成的工作区文件中不变的部分。
最后,我们覆盖了write_comps方法。该方法是我们的工作区创建器中完成主要工作的地方,一个工作区创建器有许多组可用的数据:我们可以通过get_projects方法来获取到项目文件列表的引用;而项目相关信息则可以通过get_project_info方法来获取,该方法返回一个数组引用,数组中的每一个元素是另外一个引用,该引用包含了项目名称、项目依赖项以及可选的项目guid。
4.2.4 MPC.pm与MWC.pm
添加一个新的工作区和项目类型最简单部分可能就是修改MPC.pm和MWC.pm模块了。每一个文件都有一个包含一个名为“ new”方法的“子函数区”。该方法包含了一个名为creators的字符串数组,该数组包含了可用的项目创建器(MPC.pm)和工作区创建器(MWC.pm),唯一需要我们做的事情就是添加FictionalProjectCreator到MPC.pm中的creators列表,并添加FictionalWorkspaceCreator到MWC.pm中的creators列表中去。需要注意的一点就是新类型不能添加到数组的开头,因为数组中的第一个类型是作为缺省类型存在的,而且不应该被改变。这些工作做完后,命令行选项将会自动被更新来体现出我们在这里做的修改。
到这里,关于MPC的介绍就告一段落了。
|
|