以下内容适用于RAD Studio XE4版本,但也可能适用于早期或更高版本。此外,在使用此方法时,.groupproj中定义的依赖关系将不会被执行。我尝试并行处理的.groupproj没有项目间的依赖关系,因此我不知道如何处理。
如果您使用Build
、Clean
或Make
目标使用MSBuild构建.groupproj文件,则构建不会并行运行,因为这些目标使用CallTarget
任务执行其他目标,但是CallTarget
不会并行执行其目标。
为了并行构建单独的项目,MSBuild项目必须使用单个MSBuild
任务同时构建多个项目。必须像这样定义目标:
<Target Name="Build">
<MSBuild Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Clean">
<MSBuild Targets="Clean" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Make">
<MSBuild Targets="Make" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
将这些内容添加到.groupproj文件中,然后删除其他的<Target>指令以及<Import>指令。(CodeGear.Group.Targets定义了一些目标,以便按正确顺序构建项目并在您要求仅构建项目子集时构建依赖项,但它会覆盖在.groupproj文件中定义的Build、Clean和Make目标。)请注意,这只允许您构建所有项目,而不仅是子集。
MSBuild 3.5中添加了BuildInParallel选项。 但是,由于.groupproj文件没有指定ToolsVersion属性,MSBuild将使用版本2.0中定义的MSBuild任务,该任务不支持BuildInParallel。有两种解决方法:
- 将
ToolsVersion="3.5"
(或更高版本)添加到.groupproj文件的根<Project>
元素中。
- 使用命令行参数
/toolsversion:3.5
(或缩写形式/tv:3.5
)运行MSBuild(/toolsversion
将覆盖所有项目文件中指定的ToolsVersion)。
完成此操作后,请使用/maxcpucount
(或/m
)参数运行MSBuild,您的项目将可以并行构建。但是,RAD Studio无法正确处理转换后的项目组,因此您可能需要为文件命名不同的扩展名,以清楚地表明这不是标准的RAD Studio项目组(任何以proj
结尾的扩展名均可)。
以下XSLT样式表执行上述转换:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
exclude-result-prefixes="msbuild"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
xmlns:msbuild="http://schemas.microsoft.com/developer/msbuild/2003"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="//msbuild:Project">
<xsl:copy>
<xsl:attribute name="ToolsVersion">3.5</xsl:attribute>
<xsl:apply-templates select="@* | node()"/>
<Target Name="Build">
<MSBuild Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Clean">
<MSBuild Targets="Clean" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Make">
<MSBuild Targets="Make" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
</xsl:copy>
</xsl:template>
<xsl:template match="//msbuild:Target">
</xsl:template>
<xsl:template match="//msbuild:Import">
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您可以使用MSBuild(4.0或更高版本:XslTransformation
在MSBuild 4.0中添加)通过此项目文件应用此样式表(其中groupproj2parallel.xslt
是上面的XSLT文件):
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build" Inputs="$(InputPaths)" Outputs="$(OutputPaths)">
<XslTransformation
XmlInputPaths="$(InputPaths)"
XslInputPath="groupproj2parallel.xslt"
OutputPaths="$(OutputPaths)" />
</Target>
</Project>
你需要在命令行上明确指定/p:InputPaths="..." /p:OutputPaths="..."
,或者在MSBuild
任务的Properties
参数中指定它们。(或者,您可以在项目文件中直接硬编码文件名。)
对于C#和Visual Basic项目提供的MSBuild目标定义通过使用项目文件中定义的<ProjectReference>
项处理依赖项,而不是在解决方案文件中定义依赖项。 Delphi .dproj文件和C ++ Builder .cbproj文件不支持此功能,因为底层的CodeGear.Common.Targets
没有重用Microsoft.Common.Targets
中定义的<ProjectReference>
机制。