The link time for one of our projects has become fairly bad (80+ seconds) as we've upgraded from VS2008 to 2010 and then 2012. Since even the slightest change requires a relink to test, this is a huge productivity killer and I'm looking for any suggestions of how to improve things or diagnose the bottleneck. Some facts:
- Solution is an 64-bit app that uses both MFC and ATL (through dlls). It consists of 5 small C++ projects, 7 small C# ones, and one gigantic C++/CLI one.
- Machine has a Xeon W3690 3.47 GHz CPU with 12G RAM and fast hard disks.
- Not using link time code generation or whole program optimization.
- Not using incremental linking and can't due to presence of MSIL modules. However, we have a few otherwise comparable projects that disable incremental linking for the same reason and still give ok link times.
- Example linker output when using the /time switch:
Finished searching libraries 1> Generate Transitions: Total time = 0.187s 1> MD Finalize: Total time = 1.638s 1> Pass 1: Interval #1, time = 34.507s 1> Wait PDB close: Total time = 7.114s 1> Pass 2: Interval #2, time = 43.103s 1> Final: Total time = 77.610s 1> Final: Total time = 79.015s
- Occasionally, an individual linker pass will take 300 seconds or more instead of the typical 30-45 for no clear reason.
- You can observe 5 separate "Searching libraries...[list of libs]...Finished searching libraries" cycles when linking with /VERBOSE:Lib
- Linking against a total of about 70 static libraries according to the /VERBOSE:Lib output. This includes all the various default libraries and runtimes--only about 15 of those are things we're linking against manually.
- Project makes extensive use of templated stl classes (vector, shared_ptr, etc.), and we have plenty of templated stuff of our own.
- During the link, only 3-5 out of 12 CPU cores/threads are active at all and none is maxed out.
- Putting the intermediate and output directories on a RAM disk makes no difference whatsoever, so I don't believe the process is I/O bound.
- Disabling the virus/malware scanner makes no difference.
- Refactoring the giant C++/CLI project into a bunch of dlls is a fantastic idea, but would take months of work (at least).
Since I've played with pretty much every linker setting there is without achieving any improvement, I'm starting to resign myself to the likelihood that that our code structure is simply creating a lot of work for the linker and there's not much to be done about it, but I'm hoping I'm wrong. What I'd really like is some way to figure out what kind of repeated effort the linker is making so I would have some idea where to focus my refactoring efforts, but the /VERBOSE output doesn't really help with that.
Thanks for any help you can provide.