2009-02-16 37 views
0

查看此MSDN發佈了一些背景信息:Using metadata to call a target multiple times with different parameters如果我的MSBuild腳本使用批處理在目標上「循環」,那麼也要對它進行批處理嗎?

提出的解決方案是在任務的輸出屬性中使用元數據來強制任務的批處理。

恰巧我們的構建步驟是分區分幾個目標的。我的要求是依賴在一個內循環中順序運行。

我想這個概念脫離與下面的腳本:

<?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 

回答

1

我確定在這裏看到問題爲

<Exec Command="echo step 1 %(BuildFile.InstallerFileName)" /> 

將在InstallerFileName輸出上反覆迭代。我認爲你可以調用一個自定義目標,並且該目標貫穿你的每一個步驟。從與MSBuild任務,像這樣的主腳本調用此目標:

<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> 

+0

我曾希望避免必須進行自定義構建步驟,但這看起來似乎是現在最實用的解決方案。我故意將%(BuildFile.InstallerFileName)元數據放在每個任務上強制它迭代。由於MSBuild設計,每個目標只會被調用一次。 – Jeremy 2009-02-16 13:22:16

0

當你明確目標依賴關係,你正在定義一個依賴關係樹。只要順序不違反任何依賴關係,MSBuild就可以按照它認爲合適的順序執行目標,包括並行執行(使用/m時)。

對於您的情況,MSBuild首先選擇運行step 1 MyInstaller1.msi + step 1 MyInstaller2.msi,如果您添加/m,它們可能會並行運行。如果它們不能並行運行,那麼這可能是您設計中的一個限制 - 可能共享相同的中間文件 - 並且您應該修復此問題。

如果你想要的輸出這樣的性能方面的原因,你不能解釋給MSBuild,我想你可以使用上面描述的<MSBuild>黑客。