Why are the C# pre-build and post-build events not called if I import a custom target with my own build target in it?
I have a C# project file, which I modified by importing my own custom target file. Inside the target, I have defined a "Build" target which will be called when I do the build from the Visual Studio IDE or from the MSBUILD command line.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Message Text="Custom Build started" Importance="high"/>
</Target>
</Project>
The "Build" target from the custom target file is getting called if I do the build from the Visual Studio IDE or from the MSBUILD command line. But, the pre-build and post-build events configured inside the project file is not getting called after importing my own custom target file.
It will be great if anybody could suggest what kind of change I have to make in my target file to call the pre-build event before calling the "Build" target from my target file, and the post-build event after the "Build" target.
Your custom Build
target is overriding the project system provided Build
target.
As of the time of writing this answer, the project system Build
is defined as follows:
<!--
============================================================
Build
The main build entry point.
============================================================
-->
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Returns="@(TargetPathWithTargetPlatformMoniker)" />
The definition of the CoreBuild
target is where the PreBuildEvent
and PostBuildEvent
targets are introduced to the target chain.
As of the time of writing this answer, CoreBuild
is defined as follows:
<!--
============================================================
CoreBuild
The core build step calls each of the build targets.
============================================================
-->
<PropertyGroup>
<CoreBuildDependsOn>
BuildOnlySettings;
PrepareForBuild;
PreBuildEvent;
ResolveReferences;
PrepareResources;
ResolveKeySource;
Compile;
ExportWindowsMDFile;
UnmanagedUnregistration;
GenerateSerializationAssemblies;
CreateSatelliteAssemblies;
GenerateManifests;
GetTargetPath;
PrepareForRun;
UnmanagedRegistration;
IncrementalClean;
PostBuildEvent
</CoreBuildDependsOn>
</PropertyGroup>
<Target
Name="CoreBuild"
DependsOnTargets="$(CoreBuildDependsOn)">
<OnError ExecuteTargets="_TimeStampAfterCompile;PostBuildEvent" Condition="'$(RunPostBuildEvent)'=='Always' or '$(RunPostBuildEvent)'=='OnOutputUpdated'"/>
<OnError ExecuteTargets="_CleanRecordFileWrites"/>
</Target>
Because you override Build
and your override doesn't have DependsOnTargets="$(BuildDependsOn)"
, CoreBuild
is not in the target chain. Then because CoreBuild
is not in the target chain, its dependencies, including PreBuildEvent
and PostBuildEvent
, are not in the target chain.
You could change your custom build to something like the following which sets a target chain that includes PreBuildEvent
and PostBuildEvent
.
<Target Name="Build" DependsOnTargets="PreBuildEvent;CustomBuild;PostBuildEvent"/>
<Target Name="CustomBuild">
<Message Text="Custom Build started" Importance="high"/>
</Target>
If what you actually need is a "utility" project that doesn't actually build, see the "Microsoft.Build.NoTargets" project SDK.