Как работает опция -u для ld и когда она полезна?

Я скопирую раздел из файла 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.

Как вы действительно используете эту опцию? Как в том, как мне инициировать связывание дополнительных модулей в моем исходном коде, и когда эта опция действительно полезна?

Ответ 1

Я нашел пример с интересным вариантом использования. В то время как Росс очень хорошо разбирается в DLL, вот как вы можете использовать опцию -u.

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() {
}

Теперь, когда мы связываем, мы можем выбрать, будет ли объект A добавлен в factory или нет, на основе того, передаем ли мы -u linker_a в командной строке ld. Если мы передадим его в командной строке, экземпляр A будет добавлен в factory, иначе он не будет.

Это позволяет развивать main.cpp и Factory. {cpp, h} не зависящим от A. {cpp, h} (т.е. Factory.cpp не должен включать Ah для того, чтобы экземпляр A, который будет добавлен в список объектов).

Таким образом, связывание дополнительных модулей ( "A" ) запускается флагом компоновщика -u.

Очень аккуратная функция!

Ответ 2

Это полезно для извлечения объектного файла из статической библиотеки, на которую иначе нет ссылок в вашем коде. При связывании со статической библиотекой компоновщик использует только объекты из нее, которые удовлетворяют неопределенным символам.

Существует не так много реальных вариантов использования этой опции. Обычно нет смысла связывать объект, на который иначе нет ссылки. Предположительно, если бы это было полезно, на него бы ссылались где-то. Таким образом, должен быть какой-то странный побочный эффект его включения.

Единственный реальный пример, который я могу привести, - это использование аналогичной опции компоновщика Microsoft под Windows. Я хотел превратить библиотеку сообщений об ошибках DirectX (DXERR.LIB) в DLL, поэтому я использовал команду, подобную следующей:

link /machine:ix86 /dll /out:dxerr.dll /base:0x400000
    /include:[email protected] /export:[email protected]
    /include:[email protected] /export:[email protected]
    dxerr.lib mscvrt.lib user32.lib kernel32.lib 

Переключатели /include эквивалентны опции ld -u. Если бы я не включил эти переключатели, я бы получил пустую DLL без экспортируемых из нее функций.