Существуют допустимые варианты использования --whole-archive
при связывании исполняемого файла со статическими библиотеками. Одним из примеров является создание кода C ++, где глобальные экземпляры «регистрируются» в своих конструкторах (предупреждение: непроверенный код):
main.cc
typedef void (*handler)(const char *protocol);
typedef map<const char *, handler> M;
M m;
void register_handler(const char *protocol, handler) {
m[protocol] = handler;
}
int main(int argc, char *argv[])
{
for (int i = 1; i < argc-1; i+= 2) {
M::iterator it = m.find(argv[i]);
if (it != m.end()) it.second(argv[i+1]);
}
}
http.cc (часть libhttp.a)
class HttpHandler {
HttpHandler() { register_handler("http", &handle_http); }
static void handle_http(const char *) { /* whatever */ }
};
HttpHandler h; // registers itself with main!
Обратите внимание, что в http.cc
нет символов, которые нужны main.cc
. Если вы связываете это как
g++ main.cc -lhttp
вы не получите обработчик http, связанный с основным исполняемым файлом, и не сможете вызвать handle_http()
. Сравните это с тем, что происходит, когда вы ссылаетесь как:
g++ main.cc -Wl,--whole-archive -lhttp -Wl,--no-whole-archive
Такой же стиль "саморегистрации" возможен и в обычном C, например с расширением __attribute__((constructor))
GNU.