Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSBuild batching multiple inputs into each output

Tags:

msbuild

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?

like image 333
Mikayla Hutchinson Avatar asked Aug 03 '11 18:08

Mikayla Hutchinson


1 Answers

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>
like image 59
Thomas Gerstendörfer Avatar answered Nov 07 '22 17:11

Thomas Gerstendörfer