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

2

14

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?

Leaden answered 18/7, 2014 at 21:26 Comment(3)
How is this a c++ question?Peng
I'm looking for a c++ source code exampleLeaden
The only additional information I've been able to find is that This option is equivalent to the EXTERN linker script command., but the information on that command is the same but with a note that it's equivalent to -u.Killian
L
4

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!

Leaden answered 21/7, 2014 at 15:4 Comment(0)
D
6

It's useful for pulling in an object file from a static library that otherwise isn't referenced in your code. When linking with a static library the linker only uses objects from it that satisfy undefined symbols.

There aren't a lot of realistic use cases for this option. There's usually no point in linking in an object that's otherwise unreferenced. Presumably if it was useful it would be referenced somewhere. So there would have to be some odd side effect of having it included.

The only real example I can give you is one using a similar option of Microsoft's linker under Windows. I wanted to turn the DirectX error message library (DXERR.LIB) into a DLL, so I used a command similar to the following:

link /machine:ix86 /dll /out:dxerr.dll /base:0x400000
    /include:_DXGetErrorStringA@4 /export:_DXGetErrorStringA@4
    /include:_DXGetErrorStringW@4 /export:_DXGetErrorStringW@4
    dxerr.lib mscvrt.lib user32.lib kernel32.lib 

The /include switches are equivalent of ld's -u option. If I'd had left those switches out I would've gotten an empty DLL with no functions exported from it.

Dissever answered 19/7, 2014 at 2:18 Comment(0)
L
4

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!

Leaden answered 21/7, 2014 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.