2013-07-30 18 views
1

我在使用MSBuild編寫腳本時存在以下問題: 我使用兩個元數據「metadata1」和「metadata2」創建默認項目「itemA」,其中metadata2引用metadata1。MSBuild:如何更新項目中的默認元數據?

當我稍後定義itemA並覆蓋metadata1時,metadata2仍包含metadata1的默認值。我怎樣才能讓metadata2引用「新」元數據1?

圖解如下代碼:

<ItemDefinitionGroup> 
    <itemA> 
     <Metadata1>default</Metadata1> 
     <Metadata2>%(itemA.Metadata1)</Metadata2> 
    </itemA> 
    </ItemDefinitionGroup>  
    <ItemGroup> 
    <itemA Include="first" > 
     <Metadata1>m_data1</Metadata1> 
    </itemA> 
    </ItemGroup> 

但見打印

<Message Text="itemA.Metadata1 = %(itemA.Metadata1)" /> 
<Message Text="itemA.Metadata2 = %(itemA.Metadata2)" /> 

提供:

itemA.Metadata1 = m_data1  ***<-- correctly updated*** 

itemA.Metadata2 = default  ***<-- why showing the default value, not* m_data1??** 

我怎樣才能使itemA.Metadata2具有相同的價值itemA.Metadata1更新後?

回答

1

我想是因爲評價Item Definitions - Value Sources - Note的順序,這是不可能的:因爲ItemDefinitionGroup元素的ItemGroup元素之前處理來自的ItemGroup

項目的元數據是不是在ItemDefinitionGroup元數據聲明有用。

你必須的ItemGroup

<ItemDefinitionGroup> 
    <itemA> 
     <Metadata1>default</Metadata1> 
     <Metadata2>%(Metadata1)</Metadata2> 
    </itemA> 
    </ItemDefinitionGroup>  
    <ItemGroup> 
    <itemA Include="first" > 
     <Metadata1>m_data1</Metadata1> 
     <Metadata2>%(Metadata1)</Metadata2> 
    </itemA> 
    </ItemGroup> 
+0

謝謝你的幫助。最終,我意識到,當我以不同的方式解決問題時,最好不要從同一個項目調用元數據。 – Ben

1

至於palo states覆蓋意達的Metadata2值,因爲Metadata2已經評估,你必須明確地覆蓋該值。您對Metadata1的更改不會自動傳播到初始化過程中引用它的其他位置。

但是,您可以通過啓動的MSBuild的新實例,並通過更新的元數據中的財產「重新評估」您項目的元數據。從命令行該項目運行msbuild /t:Wrapper將導致Metadata1和Metadata2打印相同的值:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup> 
    <DefaultMetadata1 Condition="DefaultMetadata1==''">default</DefaultMetadata1> 
    </PropertyGroup> 

    <ItemDefinitionGroup> 
    <itemA> 
     <Metadata1>$(DefaultMetadata1)</Metadata1> 
     <Metadata2>%(itemA.Metadata1)</Metadata2> 
    </itemA> 
    </ItemDefinitionGroup>  
    <ItemGroup> 
    <itemA Include="first" > 
     <Metadata1>m_data1</Metadata1> 
    </itemA> 
    </ItemGroup> 

    <Target Name="Wrapper">  
    <MSBuild 
     Projects="$(MSBuildProjectFile)" 
     Targets="Worker" 
     Properties="DefaultMetadata1=%(itemA.Metadata1)" 
    /> 
    </Target> 

    <Target Name="Worker"> 
    <Message Text="itemA.Metadata1 = %(itemA.Metadata1)" /> 
    <Message Text="itemA.Metadata2 = %(itemA.Metadata2)" /> 
    </Target> 
</Project> 

這種方法的有效性將取決於你試圖完成什麼。毫無疑問,您可以使用屬性而不是項目元數據找到替代解決方案。

儘管上述解決方案適用於您描述的情況,但它可能會很快失去控制。有可能是一個更簡單的解決方案,可能涉及一些冗餘代碼。

我的建議是使用簡單的解決方案,消除儘可能多的冗餘,你可以合理沒有發明新的方法來解決的MSBuild的小功能集。聰明的技巧在一天結束時可能不會爲你節省很多LOC,並且可能會導致代碼的可讀性變差,這使得新手很難理解正在發生的事情。

+0

是的,你是正確的,這可能是一個解決方案,但它的可讀性。無論如何,我發現一個不同的解決方案,我的原始問題。但是,感謝您使用新實例的技巧,我可能會在不同的上下文中使用它。 – Ben

相關問題