2011-02-16 56 views
4

我想用修改的元數據創建一個新的項目集合。 例如,更改ClCompile.AdditionalIncludeDirectories的分隔符。 爲了做到這一點我首先創建從AdditionalIncludeDirectories元數據項集合,然後改造它:在msbuild中過濾項目的元數據

<ItemGroup> 
    <IncludeDirs0 Include="%(ClCompile.AdditionalIncludeDirectories)"> 
    <key>@(ClCompile)</key> 
    </IncludeDirs0> 
</ItemGroup> 

<ItemGroup> 
    <IncludeDirs Include="@(IncludeDirs0 -> '-I %(Identity)', ' ')"> 
    <key>%(IncludeDirs0.key)</key> 
    </IncludeDirs> 
</ItemGroup> 

<ItemGroup> 
    <Compile Include="@(ClCompile)"> 
    <IncludeDirs>@(IncludeDirs)</IncludeDirs> 
    </Compile> 
</ItemGroup> 

的問題是如何在編譯項目組篩選IncludeDirs,使得每個編譯項目都會有其權包括dir。 (以便ClCompile標識等於IncludeDirs鍵)。 我試過添加一個條件,如:Condition="'%(IncludeDirs.key)'=='%(ClCompile.Identity)'"但沒有任何成功。
我本來可以直接使用IncludeDirs:<Message Text="%(IncludeDirs.key) : @(IncludeDirs)"/>,但我覺得這沒有意義,因爲Compile集合應該包含所有的元數據。

我在這裏錯過了什麼?

回答

4

你可以用一個額外的目標來收集需要的項目。 見MSBuild Batching

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup> 
    <ClCompile Include="1" /> 
    <ClCompile Include="2"> 
     <AdditionalIncludeDirectories>2.1;2.2;2.3</AdditionalIncludeDirectories> 
    </ClCompile> 
    </ItemGroup>    

    <Target Name="TransformClCompile" 
      Inputs="%(ClCompile.Identity)" 
      Outputs="_Non_Existent_Item_To_Batch_"> 
    <PropertyGroup> 
     <IncludeDirs>%(ClCompile.AdditionalIncludeDirectories)</IncludeDirs> 
    </PropertyGroup> 
    <ItemGroup> 
      <IncludeDirs Include="$(IncludeDirs)" /> 
      <Compile Include="@(ClCompile)"> 
      <IncludeDirs>@(IncludeDirs ->'-I %(Identity)', ' ')</IncludeDirs> 
      </Compile> 
    </ItemGroup>     
    </Target> 

    <Target Name="Build" DependsOnTargets="TransformClCompile"> 
    <Message Text="compile %(Compile.Identity) %(Compile.IncludeDirs)" /> 
    </Target> 
</Project> 

輸出:

compile 1 
    compile 2 -I 2.1 -I 2.2 -I 2.3 
+0

而不是 <目標名稱= 「TransformClCompile」 輸入= 「%(ClCompile.Identity)」 輸出= 「_ Non_Existent_Item_To_Batch _」> 我們在Microsoft使用?清潔模式.targets文件是: 當然,如果已經有一個條件,那麼你就是「和」它。 – 2012-04-02 02:38:08

3

有辦法做到這一點更簡潔的4.0+,使用屬性函數。

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup> 
    <ClCompile Include="1" /> 
    <ClCompile Include="2"> 
     <AdditionalIncludeDirectories>2.1;2.2;2.3</AdditionalIncludeDirectories> 
    </ClCompile> 
    </ItemGroup> 

    <Target Name="Build" > 

    <Message Text="compile %(ClCompile.Identity)" Condition="'%(ClCompile.AdditionalIncludeDirectories)' ==''"/> 

    <Message Text="compile %(ClCompile.Identity) /I $([System.String]::Join(' /I ', $([System.Text.RegularExpressions.Regex]::Split('%(ClCompile.AdditionalIncludeDirectories)', ';'))))" Condition="'%(ClCompile.AdditionalIncludeDirectories)' !=''"/> 

    </Target> 

</Project> 

輸出

compile 1 
compile 2 /I 2.1 /I 2.2 /I 2.3 

這並不是說漂亮,但它是一個更好一點,我想。必須使用Regex.Split來代替String.Split,因爲後者需要一個分離器數組,並且這有點棘手。

我想,MSBuild活頁夾需要一些改進。

丹(的MSBuild)