Исправлен код, не забывайте перемещаться по странице «Композиция».
// <== feed your content from here
Я согласен, что использование —whole-archive для создания исполняемых файлов, вероятно, не то, что вам нужно (из-за ссылок в ненужном коде и создания раздутого программного обеспечения). Если у них была веская причина для этого, они должны были документировать это в системе сборки, как теперь вам остается только догадываться.
Что касается вашей второй части вопроса. Если исполняемый файл связывает как статическую библиотеку, так и динамическую библиотеку, которая имеет (частично) тот же объектный код, что и статическая библиотека , то —whole-archive будет гарантировать, что во время соединения код из статической библиотеки является предпочтительным. Обычно это то, что вы хотите, когда вы делаете статическое связывание.
Существует законное использование - весь архив
при компоновке исполняемого файла со статическими библиотеками. Одним из примеров является создание кода 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-расширением.