9

I have a C++ compiled static library of about 15 classes and their member functions and stuff, and compiled, it's almost 14 megabytes. It links to Google's dense hash table library and MPIR, which is like GMP for Windows, but I did that in a plain exe and it was a few kilobytes. Why is it so massive? What can I do to reduce its size? It seems like there's other programs which are far more complicated than mine that are far smaller.

Compiled with Visual C++, command line is:

/Zi /nologo /W3 /WX- /O2 /Oi /Oy- /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE"
/D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t
/Zc:forScope /Fp"Release\ang.pch" /Fa"Release\" /Fo"Release\"
/Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue
Martin B
  • 23,670
  • 6
  • 53
  • 72
Foglio
  • 143
  • 2
  • 5
  • Can you give some more specific info? Compiler, compilation flags, etc. – Dusty Jul 26 '10 at 03:39
  • Compiled with Visual C++, command line is: /Zi /nologo /W3 /WX- /O2 /Oi /Oy- /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Release\ang.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue – Foglio Jul 26 '10 at 03:41
  • 1
    When you compile statically you have to expect a huge executable. You get everything - std lib, everything. – zdav Jul 26 '10 at 03:55
  • Just to be clear, are you creating a .lib or a .exe? If it's .exe, yes you can expect it to huge if it links to huge libraries. A .lib should be pretty small, since it expects you to link those dependencies separately. – Mark Ransom Jul 26 '10 at 04:29
  • 1
    @zdav: No; the linker will throw out facilities that you do not use. – Billy ONeal Jul 26 '10 at 04:47
  • 1
    I think that you should adjust your perceptions. Fourteen megabytes is not huge. – wilx Jul 26 '10 at 15:07

1 Answers1

21

The static library is a considerably different format the finished binary; partially because it has quite a bit more information. Essentially, the static library acts like a ZIP of all the .obj files generated from your translation units. This allows the linker to throw out unused functions, and if you're using LTCG, it allows the inliner to make cross-module decisions and other such optimizations.

Additionally, some compilation modes will embed the debugging symbols directly in the .lib, removing the need for separate .pdb files.

Generally you shouldn't need to worry about static library size; the linker will throw out all the extra information when building the final executable.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • @greyfade: Actually the compiler does that ;) – Billy ONeal Jul 26 '10 at 13:26
  • @Billy ONeal: At *link time*? – greyfade Jul 26 '10 at 16:10
  • @greyfade: No, that's done at compile time, unless you use LTCG, in which case the linker is actually the compiler back end. – Billy ONeal Jul 26 '10 at 16:14
  • @Billy ONeal: GCC produces large object files. It does no code removal, and emits nothing suitable for LTCG. (It *has* no such feature.) Binutils' `ld`, on the other hand, takes the object files and strips them of redundant and dead code while it performs relocations and linking. No LTCG in sight. – greyfade Jul 26 '10 at 16:27
  • @greyfade: It must be doing LTCG then; it's just not calling it that. A true linker doesn't know anything about the code it's looking at other than performing function fixups. – Billy ONeal Jul 26 '10 at 16:33
  • @Billy ONeal: They call it "garbage collection" http://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep It only knows about symbols and whether they're referenced. – greyfade Jul 26 '10 at 16:46
  • @greyfade: If all it knows about are symbols, how can it remove dead code? Dead code doesn't affect symbol tables. Sure, it removes unreferenced functions, but it's not doing full DCE. – Billy ONeal Jul 26 '10 at 17:19
  • @greyfade: This seems to indicate that GCC has such a feature: http://gcc.gnu.org/wiki/LinkTimeOptimization – Billy ONeal May 03 '13 at 15:34
  • @BillyONeal: It's a relatively new feature. I was aware of the work going into it at the time I made these comments, but it still seemed very far off. – greyfade May 03 '13 at 17:55
  • @greyfade: That says it was merged into GCC in Oct 2009. Your comment is July 2010... – Billy ONeal May 03 '13 at 18:29