Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between a PreBuildEvent, BeforeBuild target and BeforeCompile target in MSBuild?

I recently had to move some code from a PreBuildEvent in Visual Studio into the BeforeBuild target to make it work on AppHarbor. While doing so, I also noticed a BeforeCompile target.

What is the difference between these three seemingly similar events: PreBuildEvent, BeforeBuild Target, BeforeCompileTarget?

What can/can't be done with each, and why would you pick one over another?

like image 911
Danny Tuppeny Avatar asked May 08 '11 07:05

Danny Tuppeny


People also ask

What is target 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.

Will MSBuild compile without any target?

If MSBuild determines that any output files are out of date with respect to the corresponding input file or files, then MSBuild executes the target. Otherwise, MSBuild skips the target. After the target is executed or skipped, any other target that lists it in an AfterTargets attribute is run.

What is Target C#?

Target-typed means that an expression gets the type from the context it is used in. With C# 9.0 the new expression gets the type from the context, which means you don't have to specify the target-type explicitly to call a constructor.

What are target files?

targets is a user-defined file that provides customizations to projects under a directory. This file is automatically imported from Microsoft. Common. targets unless the property ImportDirectoryBuildTargets is set to false. For more information, Customize your build.


1 Answers

The answer to this question can be found in the Microsoft.Common.targets file which can be found (depending on wether you're using the 64-bit or 32-bit framework) at: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.target for 64-bit and C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets for the 32-bit runtime. This file defines all the steps a build of your project undergoes. Quoting the source:

<!-- ============================================================                                     Build  The main build entry point. ============================================================ --> <PropertyGroup>     <BuildDependsOn>         BeforeBuild;         CoreBuild;         AfterBuild     </BuildDependsOn> </PropertyGroup> 

The code is nice enough to explain the use of the BeforeBuild and AfterBuild target in the comments for both targets.

<!-- ============================================================                                     BeforeBuild  Redefine this target in your project in order to run tasks just before Build ============================================================ --> <Target Name="BeforeBuild"/>  <!-- ============================================================                                     AfterBuild  Redefine this target in your project in order to run tasks just after Build ============================================================ --> <Target Name="AfterBuild"/> 

This is followed by the definition of the CoreBuild target:

<PropertyGroup>     <CoreBuildDependsOn>         BuildOnlySettings;         PrepareForBuild;         PreBuildEvent;         ResolveReferences;         PrepareResources;         ResolveKeySource;         Compile;         UnmanagedUnregistration;         GenerateSerializationAssemblies;         CreateSatelliteAssemblies;         GenerateManifests;         GetTargetPath;         PrepareForRun;         UnmanagedRegistration;         IncrementalClean;         PostBuildEvent     </CoreBuildDependsOn> </PropertyGroup> 

So the Build target is just a wrapper around the CoreBuild target to enable you to perform custom steps just before or after the CoreBuild target. As can be seen above the PreBuildEvent and PostBuildEvent are listed as dependencies of the CoreBuild target. The dependencies of the Compile target are defined as follows:

<PropertyGroup>     <CompileDependsOn>         ResolveReferences;         ResolveKeySource;         SetWin32ManifestProperties;         _GenerateCompileInputs;         BeforeCompile;         _TimeStampBeforeCompile;         CoreCompile;         _TimeStampAfterCompile;         AfterCompile     </CompileDependsOn> </PropertyGroup> 

Again BeforeCompile and AfterCompile are commented in the code:

<!-- ============================================================                                     BeforeCompile  Redefine this target in your project in order to run tasks just before Compile. ============================================================ --> <Target Name="BeforeCompile"/>  <!-- ============================================================                                     AfterCompile  Redefine this target in your project in order to run tasks just after Compile. ============================================================ --> <Target Name="AfterCompile"/> 

Given this information I do not know why AppHarbor does not support Pre-, PostBuildEvent while the Build can be modified using Before-, AfterBuild.

Choosing which Target to override for which scenario depends on the moment during the build at which you wish to perform your given task. The targets do not have specific restrictions and/or benefits as to what they can accomplish. Apart from the fact that they can adapt ItemGroup's or properties that were defined/filled by previous steps.

Using nuget to bring in packages is probably best performed before the build tries to resolve the projects dependencies. So BeforeCompile is not a good candidate for this kind of action.

I hope this sheds some light on the matter. Found another nice explanation on MSDN

like image 89
Bas Bossink Avatar answered Nov 13 '22 16:11

Bas Bossink