c++linkerldlinker-flags

How does the -u option for ld work and when is it useful?


I'm copy-pasting a section from the man of ld :-

-u symbol
--undefined=symbol
  Force symbol to be entered in the output file as an undefined symbol. Doing this
  may,for example, trigger linking of additional modules from standard libraries.
  `-u' may be       repeated with different option arguments to enter additional
  undefined symbols.

How does one actually use this option? As in how do I trigger linking of additional modules in my source code, and when is this option actually useful?


Solution

  • I found an example with an interesting use case. While Ross makes a good point about DLLs, here's how you can use the -u option.

    a.cpp :-

    class A {
     public:
      static int init() {
        Factory::getInstance()->addObject(new A());
        return 0;
      }
    };
    int linker_a = A::init();
    

    Factory.cpp :-

    class Factory {
     public:
      Factory* getInstance() { return _instance; }
      void addObject(void* obj) { objects_.push_back(obj); }
     private:
      vector<void*> objects_;
      static Factory* _instance;
    };
    

    main.cpp :-

    #include "Factory.h"
    
    int main() {
    }
    

    Now when we link, we can choose whether the A object get added to the factory or not based on whether we pass the -u linker_a to the command line of ld. If we pass it on the command line, an instance of A will get added to the factory otherwise it won't.

    This allows development of main.cpp and Factory.{cpp,h} to be independent of A.{cpp,h} (i.e. Factory.cpp does not have to include A.h in order for an instance of A to be added to it's list of objects).

    So the linking of additional modules ("A") is triggered by the linker flag -u.

    Very neat feature!