вопрос о компоновщике ld: - опция целого архива

Исправлен код, не забывайте перемещаться по странице «Композиция». Composition.component




  
  
  
  
  





  
 // <== feed your content from here


41
задан 10 May 2009 в 22:17
поделиться

2 ответа

Я согласен, что использование —whole-archive для создания исполняемых файлов, вероятно, не то, что вам нужно (из-за ссылок в ненужном коде и создания раздутого программного обеспечения). Если у них была веская причина для этого, они должны были документировать это в системе сборки, как теперь вам остается только догадываться.

Что касается вашей второй части вопроса. Если исполняемый файл связывает как статическую библиотеку, так и динамическую библиотеку, которая имеет (частично) тот же объектный код, что и статическая библиотека , то —whole-archive будет гарантировать, что во время соединения код из статической библиотеки является предпочтительным. Обычно это то, что вы хотите, когда вы делаете статическое связывание.

4
ответ дан 27 November 2019 в 00:29
поделиться

Существует законное использование - весь архив при компоновке исполняемого файла со статическими библиотеками. Одним из примеров является создание кода C ++, где глобальные экземпляры «регистрируются» в своих конструкторах (предупреждение: непроверенный код):

handlers.h

typedef void (*handler)(const char *data);
void register_handler(const char *protocol, handler h);
handler get_handler(const char *protocol);

handlers.cc (часть libhandlers.a)

typedef map<const char*, handler> HandlerMap;
HandlerMap m;
void register_handler(const char *protocol, handler h) {
   m[protocol] = h;
}
handler get_handler(const char *protocol) {
   HandlerMap::iterator it = m.find(protocol);
   if (it == m.end()) return nullptr;
   return it->second;
}

http.cc ( часть libhttp.a)

#include <handlers.h>
class HttpHandler {
  HttpHandler() { register_handler("http", &handle_http); }
  static void handle_http(const char *) { /* whatever */ }
};
HttpHandler h; // registers itself with main!

main.cc

#include <handlers.h>
int main(int argc, char *argv[])
{
   for (int i = 1; i < argc-1; i+= 2) {
      handler h = get_handler(argv[i]);
      if (h != nullptr) h(argv[i+1]);
   }
}

Обратите внимание, что в http.cc нет символов, необходимых для main.cc . Если вы свяжете это как

g++ main.cc -lhttp -lhandlers

, вы не получите обработчик http, связанный с основным исполняемым файлом, и не сможете вызывать handle_http () . Сравните это с тем, что происходит, когда вы ссылаетесь как:

g++ main.cc -Wl,--whole-archive -lhttp -Wl,--no-whole-archive -lhandlers

Тот же стиль «саморегистрации» также возможен в простом C, например, с __ атрибутом __ ((конструктор)) GNU-расширением.

67
ответ дан 27 November 2019 в 00:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: