I have defined several AfterBuild - Tasks in my Visual Studio project with different conditions:
<Target Name="AfterBuild" Condition="'$(Configuration)'=='FinalBuilder'"> <Message Importance="high" Text="--- AfterBuild for FinalBuilder ---" /> </Target> <Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'"> <Message Importance="high" Text="--- AfterBuild for MvcBuildViews ---" /> </Target>
But only the last one is executed if the condition match. If I choose the FinalBuilder-Configuration, the AfterBuild tasks is ignored and not executed. If I change the order of the Targets in the project files (Condition="'$(Configuration)'=='FinalBuilder'" as last one), the AfterBuild for FinalBuilder-Configuration is executed but the one for MvcBuildViews is ignored.
Is the order of the target important? Is only the last AfterBuild task taken into account? Or how can I define different AfterBuild tasks with different Conditions?
Thanks
Konrad
BeforeBuild, AfterBuild. Tasks that are inserted in one of these targets will run before or after everything else in the build. Note: The BeforeBuild and AfterBuild targets are already defined in comments at the end of most project files, allowing you to easily add pre- and post-build events to your project file.
The build ordering you expect here is C, then B, then A, and Visual Studio shows that correctly in the Build Order tab, as you see below. Of course a real case would have more projects in it, but it would boil down to this case.
The associated MSBuild git issue recommends not using BeforeBuild/AfterBuild as task names going forward, instead name the task appropriately and wiring up against targets <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net46</TargetFramework> </PropertyGroup> <!--
The Visual Studio build process is defined by a series of MSBuild.targets files that are imported into your project file. One of these imported files, Microsoft.Common.targets, can be extended to allow you to run custom tasks at several points in the build process.
The only second one is executed because it was redefined. See MSDN (Declaring targets in the project file chapter).
You should use only one AfterBuild target in your project file like this:
<Target Name="AfterBuild" > <Message Condition="'$(MvcBuildViews)'=='true'" Importance="high" Text="--- AfterBuild for MvcBuildViews ---" /> <Message Condition="'$(Configuration)'=='FinalBuilder'" Importance="high" Text="--- AfterBuild for FinalBuilder ---" /> </Target>
EDIT: Or use CallTarget task:
<Target Name="AfterBuild" > <CallTarget Condition="'$(MvcBuildViews)'=='true'" Targets="MvcBuildTarget" /> <CallTarget Condition="'$(Configuration)'=='FinalBuilder'" Targets="FinalBuilderTarget" /> </Target> <Target Name="MvcBuildTarget"> <Message Importance="high" Text="--- AfterBuild for MvcBuildViews ---" /> </Target> <Target Name="FinalBuilderTarget" > <Message Importance="high" Text="--- AfterBuild for FinalBuilder ---" /> </Target>
If you really need to run multiple AfterBuild tasks (this may be the case for example if you need different Input and Output sets for each task) you can use DependsOnTarget to simply make AfterBuild depend upon all of them:
<Target Name="AfterBuild1" Inputs="stuff" Outputs="stuff"> <Message Text="Running first after build task." Importance="high" /> <Exec Command="stuff" /> </Target> <Target Name="AfterBuild2" Inputs="other stuff" Outputs="other stuff"> <Message Text="Running other after build task." Importance="high" /> <Exec Command="stuff" /> </Target> <Target Name="AfterBuild" DependsOnTargets="AfterBuild1;AfterBuild2" />
If you need to constrain their order, just make AfterBuild2 depend on AfterBuild1 with DependsOnTargets="AfterBuild1"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With