Object Linking with Static Libraries in Visual Studio

One of my favorite features of C++ is the ability for constructors to run code. This allows for the creation of some interesting objects whose sole purpose is only to run a little bit of code. Here is an example:

Using this SAY_WORD macro is quite easy. It can be placed at global scope anywhere in a cpp file, and the word it contains will indeed be said.

Important registration operations can be performed by global objects like the one above. Often times the global registrator object may never even be referenced in the program as its only purpose is to perform some registration upon program start. This is perfectly fine if you’re working in Visual Studio with a single project in your solution. The problem is when you want to start spreading code over multiple projects. Microsoft’s linker is quite over-zealous and strips away objects that don’t seem to be referenced anywhere throughout the entire solution.

A way to force linking of such objects is needed in order to ensure that global registration objects aren’t stripped by the linker. As a result of such need I came up with a compiler-specific solution that works for all my needs on Visual Studio 2010 and 2012 (probably works with earlier versions too).

The above macro can be placed into a header and it will force the compiler to link the object. In order to force linking the linker flag /INCLUDE needs to be used. However, the name of the symbol representing an object is required to be passed in. In Visual Studio a single underscore is appended to object names, and a stringizing macro can be used to generate the name of whatever global variable you’re instantiating.

To further ensure that the macro works I tried to prevent any C++ name mangling by externing the object as a C style object.

I have made prolific use of this style of macro in my custom C++ reflection, along with factory registration, along with some other things. Hopefully this trick can be of use to others as well.

TwitterRedditFacebookShare

3 thoughts on “Object Linking with Static Libraries in Visual Studio

  1. Sean

    Holy poop I’d searched so much for a solution for this over the course of years.  You win at C++.

    Reply
  2. Sean

    So a better approach I’ve found is to set the “Use Library Dependency Inputs” to Yes under Linker/General in the target .exe/.dll project. With GCC, specify the –whole-archive setting. Essentially this option makes it so that the .obj files in a .lib are treated as if they’re part of the target’s project and always linked in. I’m unsure how this will impact link times as I haven’t tried it on a suitably large project with both this and other methods just yet. It is still compatible with /OPT:REF though.

    Reply
  3. Sean

    Just as a follow up, a test we just did on one particular engine (not necessarily representative of all codebases) showed that turning on “Use Library Dependency Inputs” had absolutely no effect on link time, so for us it is safe to just turn on and use.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *