How to configure MSBuild to do some tasks only on release builds? - visual-studio

I just learned about how to include FxCop on a build. But it's slow and I want it to be done just only on release builds. Is there any way to configure that?

Check the configuration condition.
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release' ">
<FxCop TargetAssemblies="#(OutputAssemblies)"
RuleLibraries="#(FxCopRuleAssemblies)"
DependencyDirectories="$(MSBuildCommunityTasksPath)"
FailOnError="False"
ApplyOutXsl="True"
OutputXslFileName="C:\Program Files\Microsoft FxCop 1.32\Xml\FxCopReport.xsl"
DirectOutputToConsole="true"/>
</Target>

Haven't tested this but I think it should be something along the lines of:
<Target Name="MyTarget" Condition="'$(FlavorToBuild)'=='Release'">
...do release specific stuff...
</Target>

Add a condition in the .msbuild script.
Only execute the FxCop task if Configuration is "Release" not f.ex when it is "Debug"

Related

How to add a project or target to msbuild solution that builds other projects in the same solution?

Wondering if there is an easy way to do what I want with Visual Studio solution.
I have a solution that has 10+ VC++ projects. These projects don't have any dependencies on each other. I want to create msbuild target on the solution that goes and builds all the sub projects.
Something like:
msbuild mysolution.sln /t:RebuildAll /p:Configuration=Debug
How do I add "RebuildAll" target to my solution that iterates all projects in the solution and invokes "Rebuild" target on them?
Thanks
According to your description I make some test, you can refer to the following steps:
Create a file named test.proj
Use this code in the file, remember to change your own solution path in the code:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectFile Include="Your solution path/**/*.vcxproj">
<Properties>Configuration=Release</Properties>
</ProjectFile>
</ItemGroup>
<Target Name="BuildAll">
<MSBuild Projects="#(ProjectFile)" BuildInParallel="true" />
</Target>
</Project>
Then use this msbuild command line to build your projects msbuild test.proj -t:BuildAll -v:normal -m:30.

Trick to run different pre/post build events when building with MSBuild or from Visual Studio IDE

Don't ask me why, but does anyone know any trick to put in the pre/post build event command that will run different commands if the project is being built from command line with MSBuild or from inside the Visual Studio IDE?
The easiest solution would be to define build targets that are conditioned on the $(BuildingInVisualStudio) property that visual studio sets to true when buildinging.
<Target Name="SpecialPreBuild" BeforeTargets="BeforeBuild" Condition="'$(BuildingInVisualStudio)' != 'true'">
<Exec Command="some-command.exe --magic" />
<Copy SourceFiles="foo.txt" DestinationFolder="bin\$(Configuration)\bar" />
</Target>
<Target Name="SpecialPostBuild" AfterTargets="AfterBuild" Condition="'$(BuildingInVisualStudio)' != 'true'">
<Exec Command="some-other-command.exe --magic" />
</Target>
If you want to skip these targets in other IDEs / editors as well, you could introduce a custom property as well and change the Condition attributes above to
Condition="'$(PerformSpecialLogic)' == 'true'"
That way no "default" builds will execute these targets and you could build with the following arguments in your build script / CI definition:
msbuild /p:PerformSpecialLogic=true

Can I build multiple configurations of a project within one solution configuration?

I would like to build the same project twice in the same solution configuration, varying some #define flags to toggle features. Both binaries will be deployed with different names.
The solutions that I know could work:
Add a solution configuration - But I will then need to build the solution twice, which I would prefer to avoid. Both project configurations will always be built.
Copy the project - But then I have the overhead of maintaining a new project when I only want to maintain a different configuration.
Batch build - I avoid using batch build as I use both devenv for local development and msbuild for continuous integration.
Any other ideas or suggestions?
Just figured out a way to do what you asked for. Create one msbuild file (I named mine multiple.proj) and add the script below.
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Choose>
<When Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<ItemGroup>
<ProjectToBuild Include="$(MSBuildProjectName).csproj">
<Properties>Configuration=Release</Properties>
</ProjectToBuild>
</ItemGroup>
</When>
</Choose>
<Target Name="BeforeBuild">
<Message Text="Building configuration $(Configuration)..." />
</Target>
<Target Name="AfterBuild">
<MSBuild Projects="#(ProjectToBuild)"/>
</Target>
</Project>
</type>
</this>
Import the script on your projects (csproj or vbproj):
<Import Project="..\multiple.proj" />
This script tells msbuild to build again your project with another configuration as an AfterBuild event. I used Debug/Release to make the example, but you can easily change the script to support other configurations, or make the decision to build again based on other variables.
Be careful because you're running two builds at once, so build errors can be harder to understand.
Hope this helps.

Visual Studio Project - MSBuild Target - AfterBuild - Condition - Only When Binary File Updated

I have a long afterbuild process on my Visual Studio project file's after build target, as show below.
The issue is that it always runs the AfterBuild target when I hit build even when the actual source code has not changed and the project is not compiled.
How can I have this only run when the project has been compiled and the physical binary is written or update on the disk?
<Target Name="AfterBuild">
<Exec Command=""$(ProgramFiles)\Microsoft\ILMerge\ILMerge.exe" /copyattrs /log /target:library /targetplatform:4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /Lib:"$(TargetDir)\" /keyfile:"$(ProjectDir)\Plugin.snk" /out:"$(TargetDir)\$(AssemblyName).merged.dll" "$(AssemblyName).dll" "PluginCommandCommon.dll" "Common.dll"" />
<Copy SourceFiles="$(TargetDir)\$(AssemblyName).merged.dll" DestinationFolder="$(ProjectDir)..\PluginPackage\bin\$(Configuration)\" />
</Target>
Option 1:
Instead of AfterBuild use AfterRebuild (one of MSBuild's many undocumented features):
<Target Name="AfterRebuild" >...</Target>
Option 2:
Hook up one of the incremental build's conditions:
<Target Name="AfterBuild" Condition=" '#(_SourceItemsToCopyToOutputDirectory)' != '' " >
UPDATE:
Using MSBuild Extension Pack's ILMerge task will allow better control, I.E check for each file existence:
<Target Name="ILMergeItems">
<ItemGroup>
<Input Include="C:\b\MSBuild.ExtensionPack.dll"/>
<Input Include="C:\b\Ionic.Zip.dll"/>
</ItemGroup>
<MSBuild.ExtensionPack.Framework.ILMerge
Condition="Exists('%(Input.FullPath)')"
InputAssemblies="#(Input)"
OutputFile="C:\a\MyNewAssembly.dll"/>
</Target>
There is a ComboBox in Properties>>Build Events>>Run the post-build event...if this is what you mean.

TeamCity & MSpec with sln2008 runner?

I'm currently using the sln2008 runner. Is there a way to configure TeamCity to execute MSpec tests without switching to a NAnt or MSBuild runner?
I've never done it, but you could probably add a post build Exec task that just shelled out to mspec.exe. Just throw the code from my answer linked to above (How to integrate MSpec with MS Build?) in your specs csproj and add DependsOnTargets="RunSpecs" to your AfterBuild target:
<Target Name="RunSpecs">
<PropertyGroup>
<MSpecCommand>
lib\machine\specifications\Machine.Specifications.ConsoleRunner.exe $(AdditionalSettings) path\to\your\project\bin\Debug\Your.Project.Specs.dll path\to\your\other\project\bin\Debug\Your.Other.Project.dll
</MSpecCommand>
</PropertyGroup>
<Message Importance="high" Text="Running Specs with this command: $(MSpecCommand)"/>
<Exec Command="$(MSpecCommand)" />
</Target>
<Target Name="AfterBuild" DependsOnTargets="RunSpecs">
</Target>
You may use msbuild runner. Please see How to integrate MSpec with MS Build? for description on how to integrate msbuild and mspec

Resources