1

MSBuild でスクリプトを作成する際に次の問題があります。2 つのメタデータ "metadata1" と "metadata2" を持つ既定のアイテム "itemA" を作成します。これにより、metadata2 は metadata1 を参照します。

後で itemA を定義し、metadata1 を上書きすると、metadata2 にはまだ metadata1 のデフォルト値が含まれています。「新しい」metadata1 を参照するように metadata2 を作成するにはどうすればよいですか?

以下のコードの例:

  <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 と同じ値にするにはどうすればよいですか?

4

2 に答える 2

1

パロが述べているように、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 を節約することはできず、コードが読みにくくなり、初心者が何が起こっているのかを理解するのが難しくなる可能性があります。

于 2013-08-13T05:30:35.063 に答える