|
下面的内容紧接着MPC使用介绍(一)和MPC使用介绍(二)。
3.2.2.9 自定义生成后命令
当在Define_Custom中使用postcommand时,可以使用一些伪模板变量来增加灵活性,表6中列出了只能在postcommand中使用伪变量,同时请注意<%和%>是组成变量不可缺少的部分。
表6. 生成后命令伪变量 变量 | 描述 | <%input%> | 原始命令的输入文件。 | <%input_basename%> | 原始命令的输入文件的基础名称。 | <%input_noext%> | 原始命令的输入文件去除扩展名后的名称。 | <%input_ext%> | 原始命令的输入文件的扩展名。 | <%output%> | 原始命令产生的输出文件。 | <%output_basename%> | 原始命令产生的输出文件的基础名称。 | <%output_noext%> | 原始命令产生的输出文件去除扩展名后的名称。 | <%output_ext%> | 原始命令产生的输出文件的扩展名。 | | 输出文件可以是一般的输出文件,以及由下面的变量表示的文件,如果没有满足条件的文件,则为空。 | <%source_file%> | 输出的源文件。 | <%template_file%> | 输出的模板文件。 | <%header_file%> | 输出的头文件。 | <%inline_file%> | 输出的内联文件。 | <%documentation_file%> | 输出的文档文件。 | <%resource_file%> | 输出的资源文件。 |
表7描述了可以用于command、commandflags、dependent、output_option以及postcommand关键字的伪变量。
表7. 通用伪变量 变量 | 描述 | <%temporary%> | 临时文件文件名。生成的临时文件文件名并不包括路径信息,并且对于相同的变量设置均一致。 | <%cat%> | 平台无关命令,用于将文件输出到终端。 | <%cp%> | 平台无关命令,拷贝文件。 | <%mkdir%> | 平台无关命令,创建目录。 | <%mv%> | 平台无关命令,移动文件。 | <%rm%> | 平台无关命令,删除文件。 | <%nul%> | 平台无关的空设备。 | <%gt%> | 平台无关及项目无关的大于符号。 | <%lt%> | 平台无关及项目无关的小于符号。 | <%quote%> | 项目无关的双引号。 | <%and%> | 平台无关及项目无关的与操作符。 | <%or%> | 平台无关及项目无关的或操作符。 |
3.2.3 特性文件
MPC中使用特性来表示不同的概念或者是为了能够正确生成项目所必须的外部命令。特性文件决定了MPC是否生成项目,或者在生成项目时应该使用的特性。
特性中允许使用注释(//),并且对不同特性名称赋值数字值。这些特性名称会对应的出现于mpc文件中requires和avoids关键字值中。
如果某个特性没有在特性文件中列出,或者拥有真值(1),则使该特性可用;如果某个特性拥有假值(0),则该特性将被禁用。
如果某个特性名称针对某种文件类型出现在requires关键字值中,并且该特性可用,则生成对应项目;如果该特性被禁用,则不生成对应项目。
对于avoids关键字,情况正好相反。如果某个特性名称针对某种文件类型出现在avoids关键字值中,并且该特性被禁用,则生成对应项目;如果该特性可用,则不生成对应项目。
MPC全局特性文件拥有如下预定义值:
boost = 0
mfc = 0
qt = 0
rpc = 0
zlib = 0
zzip = 0
在上面的内容中,boost、mfc、qt、rpc、zlib和zzip在生成每个项目的时候都将被禁用。如果这不是你想要的结果,则你必须采用如下四种方式中的一种来达到要求:
在config目录中创建一个项目相关的特性文件(如,make.features),并设置与项目相关的特性。
在config目录中创建一个default.features文件,并设置与项目相关的特性。
在任何喜欢的目录中创建一个特性文件,并使用-feature_file命令行选项来指定。
使用-features命令行选项来动态修改特性的值。
生成的项目文件将拥有在global.features文件中指定的特性值和你的特性文件中的值的组合。但是,如果某个特性在全局文件中被禁用,并且你想使其可用,则你只能显示的在某你的特性文件中使其可用。
3.2.4 特性项目
一个特性项目可以类似普通项目一样包含信息,但是特性项目只能作为基础项目来使用,并且用来决定子项目中哪些特性可用,哪些特性被禁用。
一个特性定义必须至少包含一个特性名称,该名称表示该特性应该可用;相反的,如果在特性名称前使用非操作(使用“!”),则表示该特性应该被禁用。在括号中可以包含多个用逗号隔开的特性。下面的例子描述了如何定义一个特性项目:
// ziparchive.mpb
feature(ziparchive) {
includes += $(ZIPARCHIVEROOT)
libpaths += $(ZIPARCHIVEROOT)/lib
libs += ziparch
}
在上面的例子中,所有从名为ziparchive的特性项目继承的项目都将拥有其中定义的信息仅当ziparchive特性可用的时候。
3.3 缺省行为
MPC被设计来尽量减少维护量,并且持续的保持着对最新的生成工具的支持。如果你的源文件有着适当的(原文properly)组织,则只需要你对mpc文件进行少量的维护就可以了。
通过使用继承以及适当的代码安排,一个TAO相关的项目的mpc文件可以简单到:
project : taoserver {
}
该项目定义可以用来生成一个拥有多个idl文件、头文件和源文件的TAO服务器项目。
适当的源文件布局可以简单总结为one directory per binary target(一个目录对应一个二进制目标),如果mpc文件所在的目录下只包含属于单一目标的文件,那么MPC的缺省行为即可满足项目需求。
当然,通常情况下,你的项目文件并不能满足这样的需求,因此,所有的缺省行为都是可以被覆盖的。下面的小节描述了MPC的缺省行为以及如何覆盖该缺省行为。
3.3.1 源文件
对一个正在开发中的项目来说,添加新的源文件以及删除旧的源文件是时常会发生的事情。如果在一个mpc文件中,遗漏了Source_Files组件列表,那么MPC会假定任何满足源文件扩展类型的文件都属于项目。对于大多数的项目类型来说,源文件扩展类型包括:.cpp、.cxx、.cc、.c和.C;但是对于vc6项目类型,Visual C++ 6只能识别.cpp、.cxx和.c,并不能识别.cc和.C。
3.3.2 模板文件
如果在一个mpc文件中,遗漏了Template_Files组件列表,那么MPC会假定任何满足模板文件扩展类型的文件都属于项目。对于大多数的项目类型来说,模板文件扩展类型包括:_T.cpp、_T.cxx、_T.cc、_T.c和_T.C;但是对于vc6项目类型,Visual C++ 6只能识别_T.cpp、_T.cxx和_T.c,并不能识别_T.cc和_T.C。
3.3.3 内联文件
同源文件一样,如果在一个mpc文件中,遗漏了Inline_Files组件列表,MPC会使用缺省值来生成。满足.i和.inl扩展类型的文件被认为是内联文件。
同时,Inline_Files组件与Source_Files组件有着特殊的交互作用:如果Source_Files组件列表有文件列出,并且Inline_Files组件被省略,则每一个源文件都会匹配一个内联文件。如果匹配的内联文件被发现或者能够从自定义命令中生成,则该文件会被添加到Inline_Files组件列表中去。
3.3.4 头文件
同源文件一样,如果在一个mpc文件中,遗漏了Header_Files组件列表,MPC会使用缺省值来生成。满足.h、.hpp、.hxx和.hh扩展类型的文件被认为是头文件。
同Inline_Files组件一样,Header_Files组件与Source_Files组件也有着特殊的交互作用:如果Source_Files组件列表有文件列出,并且Header_Files组件被省略,则每一个源文件都会匹配一个头文件。如果匹配的头文件被发现或者能够从自定义命令中生成,则该文件会被添加到Header_Files组件列表中去。
3.3.5 文档文件
如果Documentation_Files组件被省略,则缺省为以如下结尾的文件:README、readme、.doc、.html和.txt。
3.3.6 资源文件
如果Resource_Files组件被省略,则缺省为以.rc为扩展名且文件名与项目名称类似的文件。例如,如果一个目录中有三个.rc文件,同时项目名称为foo,则只有包含单词foo的.rc文件会被添加到Resource_Files组件列表中去。
3.3.7 自定义的定义文件(Custom Defined Files)
自定义的定义文件组件与Source_Files组件有着特殊的交互作用:如果automatic关键字被设置为1,则自定义命令生成的源文件将会被自动添加到Source_Files组件列表中去;另一方面,如果有任何已经在Source_Files组件列表中列出的源文件同生成的源文件相同,则不会向Source_Files组件列表中添加任何生成的源文件。
3.3.8 MPC文件举例
为了描述mpc文件的简单性,我们的例子中使用了$TAO_ROOT/orbsvcs/performance-tests/RTEvent/lib目录下的内容:
Auto_Disconnect.cpp Loopback_Supplier.h RTEC_Initializer.cpp
Auto_Disconnect.h Low_Priority_Setup.cpp RTEC_Initializer.h
Auto_Disconnect.inl Low_Priority_Setup.h rtec_perf_export.h
Auto_Functor.cpp Low_Priority_Setup.inl RTEC_Perf.mpc
Auto_Functor.h Makefile RTPOA_Setup.cpp
Auto_Functor.inl ORB_Holder.cpp RTPOA_Setup.h
Client_Group.cpp ORB_Holder.h RTPOA_Setup.inl
Client_Group.h ORB_Holder.inl RTServer_Setup.cpp
Client_Group.inl ORB_Shutdown.cpp RTServer_Setup.h
Client_Options.cpp ORB_Shutdown.h RTServer_Setup.inl
Client_Options.h ORB_Shutdown.inl Send_Task.cpp
Client_Pair.cpp ORB_Task_Activator.cpp Send_Task.h
Client_Pair.h ORB_Task_Activator.h Send_Task_Stopper.cpp
Client_Pair.inl ORB_Task_Activator.inl Send_Task_Stopper.h
Consumer.cpp ORB_Task.cpp Send_Task_Stopper.inl
Consumer.h ORB_Task.h Servant_var.cpp
Control.cpp ORB_Task.inl Servant_var.h
Control.h Peer_Base.cpp Servant_var.inl
EC_Destroyer.cpp Peer_Base.h Shutdown.cpp
EC_Destroyer.h PriorityBand_Setup.cpp Shutdown.h
EC_Destroyer.inl PriorityBand_Setup.h Shutdown.inl
Federated_Test.idl PriorityBand_Setup.inl Supplier.cpp
Implicit_Deactivator.cpp RIR_Narrow.cpp Supplier.h
Implicit_Deactivator.h RIR_Narrow.h SyncScope_Setup.cpp
Implicit_Deactivator.inl RT_Class.cpp SyncScope_Setup.h
Loopback_Consumer.cpp RT_Class.h SyncScope_Setup.inl
Loopback_Consumer.h RT_Class.inl TAO_RTEC_Perf.dsp
Loopback.cpp RTClient_Setup.cpp TAO_RTEC_Perf.dsw
Loopback.h RTClient_Setup.h Task_Activator.cpp
Loopback_Pair.cpp RTClient_Setup.inl Task_Activator.h
Loopback_Pair.h RTCORBA_Setup.cpp Task_Activator.inl
Loopback_Pair.inl RTCORBA_Setup.h
Loopback_Supplier.cpp RTCORBA_Setup.inl
下面的mpc文件(RTEC_Perf.mpc)显示了为了生成可用于生成工具的项目文件,只需要做少量工作即可:
project(RTEC_Perf) : strategies, rtcorbaevent, minimum_corba {
sharedname = TAO_RTEC_Perf
idlflags += -Wb,export_macros=TAO_RTEC_Perf_Export \
-Wb,export_includes=rtec_perf_export.h
dllflags += TAO_RTEC_PERF_BUILD_DLL
Template_Files {
Auto_Disconnect.cpp
Auto_Functor.cpp
Low_Priority_Setup.cpp
RIR_Narrow.cpp
Servant_var.cpp
Shutdown.cpp
Task_Activator.cpp
}
}
下面,我们将逐行对其进行解释:
project(RTEC_Perf) : strategies, rtcorbaevent, minimum_corba {
第1行定义了一个名为RTEC_Perf的项目,并继承了冒号后列出的基础项目。
sharedname = TAO_RTEC_Perf
第2行表示该项目为共享库项目,并且库名称为TAO_RTEC_Perf。
idlflags += -Wb,export_macros=TAO_RTEC_Perf_Export \
-Wb,export_includes=rtec_perf_export.h
第3-4行则向IDL编译器添加了一些命令行选项。
dllflags += TAO_RTEC_PERF_BUILD_DLL
接下来的第5行,向dllflags添加了在rtec_perf_export.h
头文件中需要的TAO_RTEC_PERF_BUILD_DLL宏定义。
Template_Files {
Auto_Disconnect.cpp
Auto_Functor.cpp
Low_Priority_Setup.cpp
RIR_Narrow.cpp
Servant_var.cpp
Shutdown.cpp
Task_Activator.cpp
}
第7-15行指定将列出的cpp文件作为Template_Files组件中的一部分来处理。
你可能已经注意到了,上面的文件列表中被没有列出多少文件。通过MPC中内置的缺省行为,我们并不需要这样做。我们只需要IDL_Files、Source_Files、Inline_Files和Header_Files的缺省实现即可。由于模板文件并不满足MPC内置的关于模板文件的缺省行为,所有我们在这里显示的将它们列举出来。同时我们还使用了继承来获取了许多与TAO有关的选项。
|
|