Reputation: 16153
Is it possible to dependency-check multiple inputs for each output when using MSBuild batching?
I thought I'd found a solution to this by constructing my inputs list in the metadata of the output file, as follows:
<ItemGroup>
<Foo Include="output1">
<Inputs>input1a;input1b</Inputs>
</Foo>
<Foo Include="output2">
<Inputs>input2a;input2b</Inputs>
</Foo>
</ItemGroup>
<Target Name="_CompileFoo" Outputs="@(Foo)" Inputs="%(Foo.Inputs)">
<FooCompiler Src="%(Foo.Inputs)" Out="@(Foo)" />
</Target>
However, MSBuild complains that the file "input1a;input1b" does not exist. It seems that the string->items conversion takes place before the expression evaluation.
Is there any solution to this other than writing my own dependency checking?
Upvotes: 9
Views: 4817
Reputation: 2721
Checking multiple dependencies works if the item group is set up the other way round with the compilation result as metadata.
<ItemGroup>
<Foo Include="input1a">
<Result>output1</Result>
</Foo>
<Foo Include="input1b">
<Result>output1</Result>
</Foo>
<Foo Include="input2a">
<Result>output2</Result>
</Foo>
<Foo Include="input2b">
<Result>output2</Result>
</Foo>
</ItemGroup>
<Target Name="_CompileFoo" Inputs="@(Foo)" Outputs="%(Result)">
<FooCompiler Overwrite="true" Src="@(Foo)" Out="%(Foo.Result)"/>
</Target>
And instead of manually converting the Foo
item group, you can transform this in a prerequisite target building a new item group _Foo
as follows.
<ItemGroup>
<Foo Include="output1">
<Inputs>input1a;input1b</Inputs>
</Foo>
<Foo Include="output2">
<Inputs>input2a;input2b</Inputs>
</Foo>
</ItemGroup>
<Target Name="_PrepareItemsForCompileFoo">
<ItemGroup>
<_Foo Include="%(Foo.Inputs)">
<Result>%(Foo.Identity)</Result>
</_Foo>
</ItemGroup>
</Target>
<Target Name="_CompileFoo" DependsOnTargets="_PrepareItemsForCompileFoo" Inputs="@(_Foo)" Outputs="%(Result)">
<FooCompiler Overwrite="true" Src="@(_Foo)" Out="%(_Foo.Result)"/>
</Target>
Upvotes: 18