繁体   English   中英

静态库中的符号有时会链接到可执行文件中,有时不会

[英]symbols in static library sometimes got linked into executable, sometimes not

我有一个静态库,它是使用 g++ 从 linux 上的许多 cpp 文件生成的。 一个头文件包含一个实现工厂模式的类

头文件中的伪代码如下

class Factory
{
public:
    static Factory& instance();
    Base * create(const std::string& name);
    template<class T>
      void register_class(const std::string& name);
}

template <class T>
class FactoryRegister
{
public:
    FactoryRegister(const std::string& name)
    {
       Factory::instance().register_class<T>(name);
    }
}

工厂的 cpp 文件具有实现。 在另一个 cpp 文件 Derive.cpp 中,有一个我想注册到 Factory 的类。 我定义了一个全局变量来做到这一点。 代码如下

FactoryRegister<Derive> g_register_derive("derive");

所有这些文件都被编译成一个静态库并链接到一个可执行文件。

我的理解是,由于 g_register_derive 未被任何代码引用,除非提供了整体归档选项,否则不应将其链接到可执行文件中。

奇怪的是,如果我把 g_register_derive 放在 Derive.cpp 中,这个符号确实没有链接到可执行文件中。 但是如果我将 g_register_derive 放在 Factory.cpp 中,它就会链接到可执行文件中。

我用 nm 来验证结果,还有一行代码调用Factory::instance().create("Derive")也可以用来检查 g_register_derive 是否链接。

当然,如果我提供了整体归档选项,g_register_derive 将始终链接到可执行文件中。

请参阅有关静态库的 Stackoverflow 标记 wiki以了解与静态库的链接,特别是默认情况下,静态库中的目标文件libx.a(po)仅在链接器需要时才被提取并链接到程序中。

如果链接器需要链接归档成员libx.a(po)以解析对该目标文件中定义的符号foo某些先前引用,则在libx.a(po)定义的任何其他符号bar定义libx.a(po)也链接到程序中 - 因为它是该目标文件的一部分 - 无论bar是否被程序引用。

因此,如果您在编译为po并存档为libx.a(po)源文件p.cpp定义g_register_derive ,并且您的应用程序出于任何原因需要链接libx.a(po) ,则默认情况下1 g_register_derive定义在你的程序中。

如果移动的定义g_register_deriveq.cpp ,它被编译并保存为libx.a(qo)以及您的应用程序并不需要链接libx.a(qo)以任何理由,那么g_register_derive中没有定义您的程序。


[1] 使用非默认编译和链接选项,您可以从程序中删除未使用符号的定义。 请参阅如何使用 GCC 和 ld 删除未使用的 C/C++ 符号? 和接受的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM