3

I am building various projects using the <MSBuild Projects="... markup. I am then executing some command line tools after the project is built.

E.g

<Target Name="Name">
    <MSBuild Projects="" />
    <Exec Command="" />
</Target>

I notice that the project is only built as required and get the following output when the build script is run: "Skipping target "CoreCompile" because all output files are up-to-date". This is great but how do I make my <Exec... commands use the same condition so that they are only run when necessary as well?

Update: I've implemented gregmac's suggestion but its still executing the command regardless. This is what I've got now:

<Target Name="Name">
<MSBuild Projects="">
    <Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects" />
</MSBuild>
<Exec Command="" Condition="'@(AssembliesBuiltByChildProjects)'!=''" />

Any further help is much appreciated. This is a bit of a sticking point for me.

Thanks for any tips.

Alan

Alan Spark
  • 8,152
  • 8
  • 56
  • 91

4 Answers4

2

You should be able to use the TargetOutputs parameter:

<MSBuild Projects="" >
   <Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects" />
</MSBuild>
<Message Text="Assemblies built: @(AssembliesBuiltByChildProjects)" /> <!-- just for debug -->
<Exec Command="" Condition="'@(AssembliesBuiltByChildProjects)'!=''" />
gregmac
  • 24,276
  • 10
  • 87
  • 118
  • Hi, Thanks for your suggestion and sorry for the delay in responding. I'm just getting round to trying this now. I've tried it but its still executing the command regardless of whether or not the project was built. See my updated question. Any ideas? – Alan Spark Nov 21 '10 at 11:42
  • After looking into this further, I can see that AssembliesBuiltByChildProjects does contain the name of my assembly. However, there is no difference in this value whether the project is built or not... This is a bit frustrating because it is so close. Can anyone shed any light? – Alan Spark Nov 26 '10 at 15:37
1

If you can add the following to each of your projects:

<Target Name="DoStuffWithNewlyCompiledAssembly">
    <Exec Command="" />
</Target>

... then you only need to add a property:

<Target Name="Name">
  <MSBuild Projects="" Properties="TargetsTriggeredByCompilation=DoStuffWithNewlyCompiledAssembly" />
</Target>

This works because someone smart at Microsoft added the following line at the end of the CoreCompile target in Microsoft.[CSharp|VisualBasic][.Core].targets (the file name depends on the language and MSBuild/Visual Studio version).

<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''"/>

So if you specify a target name in the TargetsTriggeredByCompilation property, your target will run if CoreCompile runs-- and your target will not run if CoreCompile is skipped (e.g. because the output assembly is already up-to-date with respect to the code).

weir
  • 4,521
  • 2
  • 29
  • 42
0

You are asking wrong question.

Exec does not have any condition, But you can have condition on Target element which can be used like this.

<Target Name="Name" Condition="@(AssembliesBuiltByChildProjects)'!=''">
    <MSBuild Projects="">
        <Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects" />
    </MSBuild>
    <Exec Command=""/>
  </Target>

<Target Name="Name" Condition="@(AssembliesBuiltByChildProjects)'==''">
    ...
</Target>
Shubham
  • 349
  • 2
  • 7
-1

I did manage to find a solution to fit my needs although it may not be the optimal solution.

See my answer to my other question here: MSBuild Post-Build

Thanks, Alan

Community
  • 1
  • 1
Alan Spark
  • 8,152
  • 8
  • 56
  • 91