Static linking

| 7 Comments

Christopher Baus bemoans the problem of getting all the libs that he wants to use linked in statically on Linux. Chris wants an executable that will run on lots of different systems with the least amount of pain for all concerned and to do this he's linking as much as he can statically so that he has a known set of functionality available.

I know this will sound like heresy, but that's pretty much my approach on Windows and it has been for a long time.

Way, way, back when I worked for Credit Suisse Financial Products (whilst Bryan Boreham was in charge of all things technical), I came to appreciate that if you are writing systems that are important to people, and that have to run reliably on machines that might be used by other people for things that you have no control over, then the way to the fewest support calls is to link statically. We did this on both Solaris and Windows platforms and it worked pretty well.

The interesting thing is that this was in addition to having very strict rules on library versioning so as to preserve binary compatibility (so that a library upgrade could often only require a relink rather than a rebuild) and rules to prevent breaking changes and preserve backwards compatibility. The simple fact was that if you wanted to put your system on a box where other people might be putting their systems then the most reliable way to do it was to have your system depend on the fewest number of things. That way there was less likelihood of someone else 'fixing' their system and breaking yours.

Sure there are all manner of good reasons for using dynamic linking but they don't really matter when the most important goal is keeping the system running as it was when you built and tested it.

Obviously on Windows platforms you can't statically link to the OS services, believe me I'd like to be able to sometimes, but you can reduce the amount of dynamic linkage that goes on by statically linking your own shared code. Most of our libraries build only as static libs; we pay the price because each of our applications is larger than it might otherwise be, but reap the benefits because we don't need to re-test all of them if we upgrade a library whilst writing a new application. IMHO, back when disks were small and memory was sparse dynamic linkage had more of a place than it does now.

7 Comments

We have the same approach here. Trouble is that on unix we often end up with binaries that are 10's of Mbs. On 'doze it's mostly xlls with a dependency on RogueWave and a few other bits and pieces. Part of the work around there is to ship almost every dll the binary might need in the same folder (on Windows 2000).

.local is a god send on windows.

You need to agressively manage your dependencies and factor your code so that you only pull in what you need. Often libraries aren't fine grained enough, you end up pulling in a huge library to use only one or two features...

Library complexity and linking to complete fluff is another issue entirely ;) I don't think we've ever done a complete line count of all our code but it's a scary amount, and the code base is a mess. No policing from the start as far as I can tell, and lots of

void foo(void *mightUseThisOneDay, int normalArg);

functions. Ah, the joy of C.

Len,

Great to have you back on the technical side. Hope you enjoyed your winter. The weather is great here in Tahoe.

My opinion is that is very difficult to make any guarantees about your program when you are dependent on libraries that you didn't install yourself. Plus dynamic binding greatly increases the complexity of installation and distribution. We have plenty of RAM and hard drive space these days, and I'm willing to waste a bit to make life easier for users and support.

The winter was great. It's VERY hard to be back in London... Still it's a great motivator, now I just need to work out how to finance the next trip now ;)

I completely agree re libraries that you dont control. There are two issues really, stability and dependency. Just yesterday I was bitten by a problem with some code I was using having a dependency on a DLL that first shipped with IE4. I didn't realise I had this dependency until I tried to test the code on a clean build NT4 box which didn't have that version of IE on it. The thing is the code I was using didnt always depend on the new code, so suddenly I find that I may or may not have a dependency on this new thing - and, of course, the code I was using didnt document this fact.

For me the main issue is stability, I don't want support calls because someone else has 'upgraded' something that I use. The problem is that it's often hard to statically link, especially on Windows what with all the COM objects you need to interact with, etc. (and yes, I know that COM objects shouldn't suffer from this problem really, but not everyone manages their GUIDs appropriately...)

The other thing with dynamic binding, at least on Windows, is that it noticably slows program start up. Windows has a system wide "loader lock" which means only one dynamic lib can be in the 'loading' or 'unloading' state at a time. This tends to mean that a statically linked program will be up and running faster than a dynamically linked one.

So my niece was showing my daughter "fun things to do on Google", and this comes up...

FWIW we have even more static linking on the current project.

Did I ever tell you about the time I met the guy who caused DLL hell?

Bryan

I'm surprised you could get more staticly linked than we were then :) Where's the current project, still at BarCap?

Re DLL hell, no, but feel free to tell us in a comment, you really should have a blog you know ;)

Leave a comment