Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force include static objects from a static library in C++ (MSVC 11)

I am trying to initialize a static object in a C++ file which is trying to auto register a class to a factory in its constructor (like any standard auto-registration problem). The problem is, this is compiled to a static library, and while linking to an executable, that is optimized away. There should have been a very simple solution to that, but surprisingly, looks like it's not that simple.

Here's my class:

In Factory.h (part of static lib project)

class DummyClass : public BaseFactoryClass
{
    int mDummyInt;
public:
    DummyClass()
    {
        std::cout << "Pretending to register myself to the factory here\n";
    }
};

In some cpp, let's say Circle.cpp (still part of the static lib project)

static DummyClass dum;

main.cpp (part of the executable)

//some code accessing the BaseFactoryClass of the Registered derived classes. 

Now, since the static object is not 'directly' used in the executable project, it's skipped from the linked library.

I want to make it work in MS VC11 (Visual Studio 2012) (and GCC 4.8.*, but that's for later). Looking at other questions, I tried various things so far, which don't seem to work:

  1. Looks like /WHOLEARCHIVE linker option is only supported from Visual Studio 2015 (We're using VS 2012)
  2. Specifying /OPT:NOREF should have worked (I tried several combination of this with other flags like /OPT:NOICF), but it doesn't work for anyone.
  3. I tried #pragma comment (linker, "/include:symbolName") in the header file, but that gives a linker error about symbol being unrecognized. (And also that wouldn't work in GCC, but probably --whole-archive works there).

There is a flag in Visual Studio Linker Settings that allows linking all object files individually rather than the static lib, but I don't want to go that route. Also, preferably I'd just want to write something in the source (.cpp) of each individual class I want to automatically register, with all the boiler plate code and macros being in a central header like BaseFactory.h etc. Is there any way to do it (even in C++ 11 where there's a guarantee that a symbol will be initialized)? Want to make the registration of a new class as easy as possible for any new developer.

like image 236
Piyush Soni Avatar asked Dec 03 '25 10:12

Piyush Soni


1 Answers

In MSVC you have a linker pragma you can use for that purpose:

#pragma comment (linker, "/export:_dum")

This way whenever the linker is run, it will force link _dum in your executable or DLL.

A better way, though, would be to consider using a DLL instead of a static library. Then you avoid this problem altogether since on each load of the DLL that static variable will be initialized.

like image 50
Alexis Wilke Avatar answered Dec 04 '25 23:12

Alexis Wilke