--whole-archive
将可执行文件与静态库链接时有合法用途。一个示例是构建 C++ 代码,其中全局实例在其构造函数中“注册”自己(警告:未经测试的代码):
处理程序.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!
主文件
#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 中使用,例如使用__attribute__((constructor))
GNU 扩展。