我有一个静态库(lib.a)和一个链接到它的程序。该库没有任何在使用之前总是被调用的入口点,但我需要在程序的早期执行一段代码(最好在main()启动之前)。因此我想我会使用自己类的静态变量。我添加了包含以下内容的新源文件:
#include <MyClass.h>
static MyClass myVar;
然后MyClass的构造函数将执行我的代码。当我链接lib.a并尝试在其上执行“nm”时,我得到myVar在那里的信息。但是,当我链接我的程序并尝试“nm”时,我没有看到myVar。当我将这段代码放入现有文件时,符号在最终的可执行文件中可见。这是为什么?在这种情况下,链接器是否可以从lib.a库中省略对象文件?我知道变量不是从外部引用的(它不能是静态的)但是它应该自己执行代码,因此我不明白为什么它应该被删除。
如果它有所作为,我正在使用一些旧的SunPro编译器。
答案 0 :(得分:1)
从技术上讲,应该强制链接器在编译程序时包含该目标文件。但是,在许多编译器中,例如MSVC++,对此的支持是错误的。在主程序中的某处添加外部引用应该强制包含该目标文件。
另请注意,在nm
的情况下,您的静态初始化程序可能是内联的,因此符号不需要存在于最终的二进制文件中。在静态中尝试一些带副作用的东西(例如std::cout
语句),并确保在指责编译器之前它没有运行:)
答案 1 :(得分:0)
事实证明,链接器的作用非常标准(我不是指C ++标准,通常只是观察者行为),你可以解决它。在GNU ld
中,它是--whole-archive
选项,在我的Sun工具中,它是-z allextract
。这对我的项目实际上没有按预期工作,所以我使用了一些带有弱符号的魔法-z weakextract
来达到我想要的效果。