Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you conditionally run an MSBuild task only when your project outputs have been built?

Tags:

msbuild

I want to run an MSBuild Task (which signs an executable/dll) but only when the output exe/dll has changed. If none of the source files have changed causing a recompile of the exe/dll then I don't want the task to run.

Despite spending several hours trying different things out I cannot work out how to get my target task to only run if the project has been compiled where the output files have changed (in other words the CoreCompile target was not skipped I think).

like image 484
RidingTheRails Avatar asked Oct 16 '10 22:10

RidingTheRails


People also ask

How do I run MSBuild task?

To execute a task in an MSBuild project file, create an element with the name of the task as a child of a Target element. If a task accepts parameters, these are passed as attributes of the element. Tasks can also return information to the project file, which can be stored in items or properties for later use.

Will MSBuild compile without any target?

If there are no initial targets, default targets, or command-line targets, then MSBuild runs the first target it encounters in the project file or any imported project files.

What is targets in MSBuild?

A target element can have both Inputs and Outputs attributes, indicating what items the target expects as input, and what items it produces as output. If all output items are up-to-date, MSBuild skips the target, which significantly improves the build speed. This is called an incremental build of the target.


1 Answers

You can just do this:

<PropertyGroup>
  <TargetsTriggeredByCompilation>DoStuffWithNewlyCompiledAssembly</TargetsTriggeredByCompilation>
</PropertyGroup>

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).

like image 152
weir Avatar answered Oct 21 '22 03:10

weir