有关某些背景信息,请参阅此MSDN帖子:Using metadata to call a target multiple times with different parameters
提出的解决方案是在Task的Output属性中使用元数据来强制批处理任务。
碰巧我们的构建步骤被划分为几个目标。我的要求是依赖关系在一种内循环中顺序运行。
我用以下脚本尝试了这个概念:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="BuildSolutions"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="3.5">
<ItemGroup>
<BuildFile Include="myscript.txt">
<InstallerFileName>MyInstaller1.msi</InstallerFileName>
<CustomTwiddleBit>true</CustomTwiddleBit>
<OtherCustomTwiddleBit>false</OtherCustomTwiddleBit>
</BuildFile>
<BuildFile Include="myscript.txt">
<InstallerFileName>MyInstaller2.msi</InstallerFileName>
<CustomTwiddleBit>false</CustomTwiddleBit>
<OtherCustomTwiddleBit>true</OtherCustomTwiddleBit>
</BuildFile>
</ItemGroup>
<Target
Name="BuildInstallers"
Outputs="OutputDir\%(BuildFile.InstallerFileName)"
DependsOnTargets="Step3"
>
<Exec Command="echo %(BuildFile.InstallerFileName)" />
</Target>
<Target Name="Step1">
<Exec Command="echo step 1 %(BuildFile.InstallerFileName)" />
</Target>
<Target Name="Step2"
DependsOnTargets="Step1">
<Exec Command="echo step 2 %(BuildFile.InstallerFileName)" />
</Target>
<Target Name="Step3"
DependsOnTargets="Step2">
<Exec Command="echo step 3 %(BuildFile.InstallerFileName)" />
</Target>
</Project>
输出如下:
Microsoft (R) Build Engine Version 3.5.30729.1
[Microsoft .NET Framework, Version 2.0.50727.3053]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 2/16/2009 20:41:14.
Project "D:\Source\test\test.proj" on node 0 (BuildInstallers target(s)).
step 1 MyInstaller1.msi
step 1 MyInstaller2.msi
Step2:
step 2 MyInstaller1.msi
step 2 MyInstaller2.msi
Step3:
step 3 MyInstaller1.msi
step 3 MyInstaller2.msi
BuildInstallers:
MyInstaller1.msi
BuildInstallers:
MyInstaller2.msi
Done Building Project "D:\Source\test\test.proj" (BuildInstallers target(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.43
任何想法如何让输出如此:
step 1 MyInstaller1.msi
step 2 MyInstaller1.msi
step 3 MyInstaller1.msi
step 1 MyInstaller2.msi
step 2 MyInstaller2.msi
step 3 MyInstaller2.msi
答案 0 :(得分:2)
我确定在这里看到了问题
<Exec Command="echo step 1 %(BuildFile.InstallerFileName)" />
将在InstallerFileName输出上反复迭代。我认为您可以调用自定义目标,并且该目标会执行每个步骤。使用MSBuild Task从主脚本调用此目标,如下所示:
<MSBuild Projects="CustomTargets.proj"
Targets="BuildInstallers"
Properties="BuildFile=%(BuildFile.InstallerFileName)" />
在BuildInstallers目标中,您将使用
<Target ="BuildInstallers" DependsOnTargets="Step3" >
</Target>
<Target Name="Step1">
<Exec Command="echo step 1 $(BuildFile)" />
</Target>
等
答案 1 :(得分:0)
当您定义目标和依赖项时,您将定义依赖关系树。只要订单不违反任何依赖关系,MSBuild就可以按照它认为合适的任何顺序执行目标,包括并行(使用/m
时)。
在您的情况下,MSBuild首先选择运行step 1 MyInstaller1.msi
+ step 1 MyInstaller2.msi
,如果您添加/m
,它们可能会并行运行。如果它们无法并行运行,那可能是您设计中的限制 - 可能共享相同的中间文件 - 您应该解决这个问题。
如果您希望输出的顺序是出于性能原因无法向MSBuild解释的,我猜您可以使用上面描述的<MSBuild>
hack。