Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to invoke the same msbuild target twice with different parameters from within msbuild project file itself

I have the following piece of msbuild code:

  <PropertyGroup>
    <DirA>C:\DirA\</DirA>
    <DirB>C:\DirB\</DirB>
  </PropertyGroup>

  <Target Name="CopyToDirA"
          Condition="Exists('$(DirA)') AND '@(FilesToCopy)' != ''"
          Inputs="@(FilesToCopy)"
          Outputs="@(FilesToCopy -> '$(DirA)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirA)" />
  </Target>

  <Target Name="CopyToDirB"
          Condition="Exists('$(DirB)') AND '@(FilesToCopy)' != ''"
          Inputs="@(FilesToCopy)"
          Outputs="@(FilesToCopy -> '$(DirB)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirB)" />
  </Target>

  <Target Name="CopyFiles" DependsOnTargets="CopyToDirA;CopyToDirB"/>

So invoking the target CopyFiles copies the relevant files to $(DirA) and $(DirB), provided they are not already there and up-to-date.

But the targets CopyToDirA and CopyToDirB look identical except one copies to $(DirA) and the other - to $(DirB). Is it possible to unify them into one target first invoked with $(DirA) and then with $(DirB)?

Thanks.

like image 545
mark Avatar asked Aug 18 '09 14:08

mark


2 Answers

You should be able to generate an ItemGroup containing the Dirs and then % on that.

<ItemGroup>
    <Dirs Include="C:\DirA\;C:\DirB\">
</ItemGroup>
<Target Name="CopyFiles"
    Condition="Exists('%(Dirs)') AND '@(FilesToCopy)' != ''"
    Inputs="@(FilesToCopy)"
    Outputs="@(FilesToCopy -> '%(Dirs)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="%(Dirs)" />
</Target>

Or you can do 2 explicit calls:

<Target Name="CopyFiles">
    <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="FilesToCopy=@(FilesToCopy);DestDir=$(DirA)" />
    <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="FilesToCopy=@(FilesToCopy);DestDir=$(DirB)" />
</Target>

<Target Name="CopyASetOfFiles"
    Condition="Exists('$(DestDir)') AND '@(FilesToCopy)' != ''"
    Inputs="@(FilesToCopy)"
    Outputs="@(FilesToCopy -> '$(DestDir)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DestDir)" />
</Target>

I haven't tested either syntax, but am relatively more confident of the second.

(The answer, if there is one, is in my Sayed Hashimi book on my desk - you'll have to wait until the first of:

  1. Get the book
  2. I get bored
  3. Sayed finds this post and comes up with a brilliant tested answer)
like image 111
Ruben Bartelink Avatar answered Oct 20 '22 03:10

Ruben Bartelink


As someone already mentiond the answer is batching.

Here are some links:

  • MSBuild Batching Part 1
  • MSBuild Batching Part 2
  • MSBuild Batching Part 3
  • MSBuild RE: Enforcing the Build Agent in a Team Build
like image 9
Sayed Ibrahim Hashimi Avatar answered Oct 20 '22 03:10

Sayed Ibrahim Hashimi