5

I'm compiling a static library that contains mainly templated classes. When this is compiled using gcc, the resulting .a file is around about the 40Mb mark. This is pretty big, but not entirely unexpected due to the amount of templating going on. However, when I compile the same code using VS2005, the resulting .lib file is coming in at (wait for it!) 575Mb..

Now, before I get burned, I have seen: How can I get my very large program to link? and this is useful for understanding that templates are potentially making the libs large, but I'm struggling to understand why the outputs from the two compilers are so different in size?

VS options are: (Debug)

/Od /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_WIN32_WINNT=0x0500" /D "_MBCS" /Gm /EHsc /RTC1 /MDd /W4 /nologo /c /Wp64 /Zi /TP /errorReport:prompt

(Release)

/O2 /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_WIN32_WINNT=0x0500" /D "_MBCS" /FD /EHsc /MD /W4 /nologo /c /Wp64 /Zi /TP /errorReport:prompt

Any comments or pointers are much appreciated..

Community
  • 1
  • 1
StevieG
  • 8,639
  • 23
  • 31
  • You are building a Debug build on VS2005 (`/D "_DEBUG"`) - is this the same as GCC? This can make quite a big difference. – Steve Townsend May 04 '11 at 14:51
  • You're right, it does.. The release build version on VS2005 is *only* 350Mb.. Still nowhere near small enough, though! – StevieG May 04 '11 at 14:54
  • Are you using Linktime code generation (LTCG)? This makes static libraries very large and then the optimizer shrinks the final code down at link-time. – Steve Townsend May 04 '11 at 14:59
  • Let's see the compiler and linker switches for your release build for both gcc and VS2005. – Mark Tolonen May 04 '11 at 15:10
  • Nope, not using whole program optimisation on the static lib compiler settings, nor LTCG on the executables linker settings. Should have mentioned in the original post though, that I am getting a much smaller exe (~20Mb) when I link to this lib, it just takes ages to link because the lib itself is so big.. – StevieG May 04 '11 at 15:32

1 Answers1

3

A debug build disables inlining and also the linker options that discard duplicate code, so you get lots of copies of every template and inline function.

You can enable it with /OPT:REF /OPT:ICF in your linker options. But it should be there by default in a release build.

Unfortunately I think that only helps with your final executable, not the intermediate library.

You might be able to save some space by explicitly instantiating the template instances you need in one .cpp, and using extern template to prevent automatic instantiation when compiling other source files.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • Yep, I'm definitely thinking along these lines to reduce the sizes in general.. but still can't get my head round why its so much better in gcc, without any explicit instantiation or other coding optimizations... – StevieG May 04 '11 at 16:06
  • Me too. I wonder if it relates to function-level linking (/Gy, implied by /O2). It's a good optimisation, but it must increase the overhead in the object files - especially if you have lots of little inline functions being generated repeatedly. You could try specifying /Gy- in release mode to see if it makes any difference. – Alan Stokes May 04 '11 at 20:00
  • Accepting this answer as its the most useful, although the problem still persists. – StevieG Feb 10 '12 at 12:39