Link to home
Start Free TrialLog in
Avatar of thrawn80
thrawn80Flag for Singapore

asked on

Reducing static library size

Dear experts,

I've been building my static library which has approximately 160,000 lines of codes.

However, I've observed 2 things,
1) The debug library is almost 1 GB
2) The release library is 500MB+

I find these sizes very prohibiting and makes it very hard to distribute via the network.

Is there something wrong?

I'm using Visual Studio 2005 SP1. My project is a pure C/C++ static library project.
I use templates quite extensively, it takes up about 30-40% of code memory approximately (due to smart pointers, data structures, etc etc etc)

I wonder if there's any options that I can set to reduce the static library size, since moving away from templates is next to impossible.

Thanks!
Jeremy
Avatar of Infinity08
Infinity08
Flag of Belgium image

Some ideas :

(a) Most compilers have an option to optimize for size. For gcc eg. that's -Os, for VC++ that's /Os
(b) As you know, heavy use of templates can cause a lot of bloat in executable size. Wherever possible, consider minimizing the use of templates.
(c) Make sure to only link in that what you actually need (especially when it comes to external libraries).
(d) Consider splitting up the huge library in several smaller more focused libraries.
(e) Wherever possible, consider linking dynamically instead of statically.
(f) if you have any data in the binary, consider moving it out of the library into separate files, and load the data from those files.
Avatar of cup
cup

Do you need to distribute both the debug and release libraries?  The debug libraries without source or .pdb are pretty useless.
Avatar of thrawn80

ASKER

Dear infinity80 and cup,

Thanks for your suggestions! I have been comtemplating whether to split this library into its namespace-sake components as individual libraries instead.

In the past, I didn't understand the linking processing at the end well. Now, if I'm not wrong, even though the dependencies to a certain extent are built into the static library, the final executable will contain only 1 unique code of the same class signature during linking.

But what I don't understand is that - how come game engines like Ogre3D can be have like 120,000+ lines of codes (estimated with a tool) and still have a relatively small static library?

I do agree that dynamic linking is much faster in terms of development but in this case, the static library is alike an application start; the final application doesn't need to define a WinMain(); it only needs to define the 2 declared and called functions in the library, ie, Init() and Release(). The static library will call these 2 functions that's expected to be implemented by the application itself otherwise linker errors will occur.

As for data, they're always loaded from external sources unless there's really by-design, no choice but to hard-code them.

And cup, yes, I need to distribute the codes as well :)

Is there any other things to look out for?

Thanks,
Jeremy
SOLUTION
Avatar of cup
cup

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just one more note about dynamic linking : I did not intend it to be for the entire library, but rather for certain of the dependencies.


>> Is there any other things to look out for?

All the other things I can think of, impact the code (probably too much), like disabling exceptions and such.
Dear all,

If I'm not wrong, static library merely preprocesses the source codes and then compiles them into .obj files.
The lib.exe will simply chain up the entire bunch of object files. Of course, no linking is done.

Here's the thing - if i reduce the amount of preprocessing required, will it decrease the size of the static library in the end?

A few ways to decrease preprocessing:
1) Use forward declarations if possible
2) Do not include unnecessary headers

Anymore ways?

I bet if I can reduce the size of the object files, I'll eventually reduce the size of the static library altogether.

Please let me know if I'm right.

Thanks,
Jeremy
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Infinitely08 and Cup for your generous insights!

I guess I roughly know what to do know. Since it's just the static library size, it should be relatively easy to implement.

I'll start slow i guess, by confirming which are the libraries that are really not needed, especially the Platform SDK libs.

I'm not sure if we're still allowed to make comments here though but if we can, please continue to share your insights if possible.

Again, I thank the both for your generosity :)
>> I'm not sure if we're still allowed to make comments here though

The question is still open for discussion, so anybody can feel free to post new insights :) Should you have a further doubt or insight about this, please don't hesitate to ask here.
One of the problems I've found with splitting static libraries is that they have to be added to the linker in the order of dependency.  Sometimes, the same library needs to appear more than once.
It'd seem that the root cause of my large library size is due to my poor header inclusion management. :(

Perhaps I'll take some time off to re-look into the engine's headers.

Thanks again!
Interestingly had to deal with this very problem for a different reason recently. We are working in an environment where all our code is statically linked and one of the systems it needs to run on has a limited program area, the executable compiled for other platforms without this restriction (or rather a considerably larger restriction) did not fit inside that area. Most of what we did has already been mentioned but there are some other things to consider.

- Use of macros, could these be replaced by actual function calls.
- Disabling in-lining where performance is not critical (this was the biggest single win for us). Again this can be done through compiler command switches or just in the properties window in VS.
>> It'd seem that the root cause of my large library size is due to my poor header inclusion management. :(

That's interesting, that would imply either or both of the following :

(a) you have (a lot of) code in header files.
(b) the compiler adds a lot of extra debugging/symbol information for each of those unnecessary includes

Was this change in size due to removing some includes something you noticed for the debug version or the release version ?