How do I speed up my large build. Do you have any tips or tricks?
Tip 1
Include this after your common .targets file include Microsoft.Common.targets to avoid calling out to RAR, if you can encourage everybody on your team to make sure that
HintPaths only use environment variables and work on every machine:
<!-- Override the default [ResolveAssemblyReferences] task with my own. Note that we also remove
[ResolveCOMReferences] because it has a hardcoded dependency on [ResolveAssemblyReferences] that
we can't override. -->
[<PropertyGroup>]
[<ResolveReferencesDependsOn>]
[ResolveNativeReferences;]
[SplitProjectReferencesByType;]
[ResolveProjectReferences;]
[ResolveVCProjectReferences;]
[NautilusResolveAssemblyReferences]
[</ResolveReferencesDependsOn>]
[<ResGenDependsOn>NautilusResolveAssemblyReferences</ResGenDependsOn>]
[</PropertyGroup>]
<Target Name="NautilusResolveAssemblyReferences" Condition="'@(Reference)'!=''">
[<CreateItem] Include="@(Reference->'%(HintPath)')" Condition="'@(Reference->'%(HintPath)')'!=''">
<Output TaskParameter="Include" ItemName="ReferencePath" />
[</CreateItem>]
[<CreateItem] Include="@(Reference)" Condition="'@(Reference->'%(HintPath)')'==''">
<Output TaskParameter="Include" ItemName="ReferencePath" />
[</CreateItem>]
</Target>
Tip 2
Build this into a DLL and then call "msbuild with /v:q /noconlog
/l:TimingLogger,TimingLogger.dll > timings.txt". Open that .txt file, sort the lines (M-x sort-lines in emacs), and then figure out what tasks are taking up the most time in your build and either replace them with faster ones or find ways to avoid using them:
using System;
using [System.Runtime.InteropServices;]
using Microsoft.Build.Framework;
public class [TimingLogger] : Microsoft.Build.Utilities.Logger
{
public override void [Initialize(IEventSource] eventSource)
{
[eventSource.TaskStartedEvent] += new [BuildEventHandler(OnTaskStarted);]
[eventSource.TaskFinishedEvent] += new [BuildEventHandler(OnTaskFinished);]
}
private [DateTime] taskStart;
private void [OnTaskStarted(object] sender, [BuildEventArgs] args)
{
taskStart = [System.DateTime.Now;]
}
private void [OnTaskFinished(object] sender, [BuildEventArgs] args)
{
[TimeSpan] duration = [System.DateTime.Now] - taskStart;
[Console.WriteLine(String.Format] ("{0} milliseconds to be: {1}, with {2}", [duration.ToString(),] args.Message, args.File));
}
}
Note: In Beta 2
MSBuild will give you timing information for free when you run it under /v:diag (diagnostic mode). So you should only do this tip Pre-Beta 2 of VS 2005
Tip 3
You can lessen the amount of work that RAR needs to do by eliminating places that it looks for assemblies. You can control this with the
AssemblySearchPaths in your targets\proj file property. This will work for 90% of projects in razzle-like environments and eliminates the need to hit the registry:
[<PropertyGroup>]
[<AssemblySearchPaths>]
-delete this line -- {CandidateAssemblyFiles};
-delete this line -- [$(ReferencePath);]
{HintPathFromItem};
{TargetFrameworkDirectory};
-delete this line -- {Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
-delete this line -- {AssemblyFolders};
-delete this line -- {GAC};
{RawFileName}
[</AssemblySearchPaths>]
[</PropertyGroup>]
Tip 4
Do a build and then build again immediately with no changes. Do you have custom targets that are executing unnecessarily? Investigate adding Inputs\Outputs to take advantage of our built-in timestamp checking