静态库中的符号有时会链接到可执行文件中,有时则不会
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);
}
}
Factory的cpp文件具有实现。在另一个cpp文件Derive.cpp中,有一个类我想注册到Factory中。我定义了一个全局变量来实现这一点。代码如下
FactoryRegister<Derive> g_register_derive("derive");
所有这些文件都被编译成一个静态库,并链接到一个可执行文件。
我的理解是,由于gregister_drive没有被任何代码引用,所以除非提供完整的归档选项,否则不应该将其链接到可执行文件中。
奇怪的是,如果我把g_register_drive放在derive.cpp中,那么这个符号确实没有链接到可执行文件中。但如果我把g_register_drive放在Factory.cpp中,它就会链接到可执行文件中。
我用nm来验证结果,还有一行代码调用Factory::instance().create("Derive")
,也可以用来检查g_register_drive是否链接。
当然,如果我提供了完整的归档选项,g_register_drive将始终链接到可执行文件中。
请参阅关于静态库的Stackoverflow标记wiki理解与静态库的链接,特别是默认情况下,只有当链接器需要时,静态库中的对象文件libx.a(p.o)
才会被提取并链接到程序中。
如果链接器需要链接存档成员libx.a(p.o)
以便解析对在该对象文件中定义的符号CCD_ 4的一些先前引用,则也在CCD_ 6中定义的任何其它符号CCD_也链接到程序中-因为它是对象文件的一部分-是否bar
是否被程序引用。
因此,如果在编译的源文件p.cpp
中定义g_register_derive
到p.o
并存档为libx.a(p.o)
,并且您的应用程序需要链接libx.a(p.o)
由于任何原因,则默认情况下1g_register_derive
变为在您的程序中定义。
如果将g_register_derive
的定义移动到q.cpp
,它被编译并归档为libx.a(q.o)
,以及您的应用程序是否因任何原因不需要链接libx.a(q.o)
,然后链接g_register_derive
未在程序中定义。
[1]使用非默认编译和链接选项,可以删除定义程序中的个未使用的符号。请参阅如何使用GCC和ld删除未使用的C/C++符号?以及被接受的答案。
- CMake:如何将库 A 链接到库 B,然后将可执行文件链接到库 A
- 如果包含映射的静态库与可执行文件和动态库链接,静态映射(变量)是否会被多次释放?
- 为什么C++可执行文件在与较新的libstdc++.so链接时运行得更快?
- 在链接可执行文件之前查找静态库未解析的依赖项
- mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库
- python37.dll在可执行文件中未链接
- 调用函数一次用于动态链接库,一次从可执行文件调用函数
- 使用共享库编译可执行文件时仅链接所需的符号
- 使用 MINGW 和 CPLEX 库链接从 Linux 编译 Windows 可执行文件
- 将我的主输出库与测试可执行文件链接时出现问题
- cmake:构建可执行文件并库并链接它们
- 在可执行文件中使用带有符号链接的相对路径
- 使用LTO静态链接的可执行文件(链接时间优化):如何使用以前构建的库进行制作
- 将 CLANG 构建的可执行文件与 G++-v6 构建的 Boost 库链接时出错
- 当使用rpath时,C++可执行文件无法找到动态链接的共享库
- cusparse功能的多个定义错误在链接可执行文件中的cuda文件时
- GTEST测试项目链接链接到其他可执行文件
- Cmake不会将共享库的链接依赖关系传播到我的可执行文件
- G++:无法与主可执行文件链接
- 是否可以在运行时将可执行文件链接到具有相对路径的共享库