链接静态库时链接器可以省略目标文件吗?

     2023-02-22     177

关键词:

【中文标题】链接静态库时链接器可以省略目标文件吗?【英文标题】:can linker omit object file when linking static lib? 【发布时间】:2010-12-05 16:39:49 【问题描述】:

我有一个静态库 (lib.a) 和一个链接到它的程序。该库没有任何入口点,在使用它之前总是会被调用,但我需要在程序的早期执行一段代码(最好在 main() 开始之前)。因此我想我会使用我自己的类的静态变量。我添加了包含以下内容的新源文件:

#include <MyClass.h>
static MyClass myVar;

然后 MyClass 的构造函数将执行我的代码。当我链接 lib.a 并尝试对其执行“nm”时,我得到了 myVar 存在的信息。但是,当我链接我的程序并在其上尝试“nm”时,我看不到 myVar。当我将这段代码放入现有文件时,该符号在最终的可执行文件中可见。这是为什么?在这种情况下,链接器可以从 lib.a 库中省略目标文件吗?我知道该变量不是从外部引用的(它不能是静态的),但它应该自己执行代码,因此我不明白为什么要删除它。

如果有什么不同,我会使用一些旧的 SunPro 编译器。

【问题讨论】:

编写依赖于全局变量初始化的代码是个坏主意。更好的事情是如何做得更好。 @ybungalobil:它可能很有用;例如单元测试。 (这是大多数 C++ 单元测试框架处理自动测试注册的方式)。 @Tomasz:您使用的是什么编译器/平台? @Billy:它可能有用,但前提是最多有一个组件依赖它。否则你会得到非常糟糕的事情(初始化顺序未定义)。他还写道,他使用“旧的 SunPro 编译器”。 @ybungalobill:我知道它有问题——但是,我的意思是这并不总是一个坏主意。是的,有一些注意事项需要注意,但这并不意味着没有人应该使用该构造。 【参考方案1】:

从技术上讲,应该强制链接器在编译程序时包含该目标文件。但是,许多编译器对此的支持存在缺陷,例如MSVC++。在主程序的某处添加外部引用应该强制包含该目标文件。

另请注意,在nm 的情况下,您的静态初始化程序可能已内联,因此该符号不需要存在于您的最终二进制文件中。在你的静态文件中尝试一些有副作用的东西(比如std::cout 语句),并确保它在责怪编译器之前不会运行:)

【讨论】:

我知道它不起作用,这就是我开始使用 nm 进行调查的原因。感谢您提供它应该正常工作的信息,但很高兴知道它是由 C++/其他标准定义还是仅在其他编译器中工作? @Tomasz:C++ 标准没有说明如何组装最终的二进制文件。 (即标准不知道静态库或动态库的存在)这是因为标准被编写为机器中立的,并且这样的库在许多架构上是不可能的(特别是那些分离代码和数据的架构)【参考方案2】:

事实证明,链接器所做的是非常标准的(我不是指 C++ 标准,只是一般的观察者行为),您可以解决它。在 GNU ld 中,它是 --whole-archive 选项,在我的 Sun 工具中,它是 -z allextract。对于我的项目,这实际上并没有按预期工作,所以我使用了一些带有弱符号的魔法 -z weakextract 来实现我想要的。

【讨论】:

当目标是静态库而目标链接是静态库时,target_link_libraries 会做啥

】当目标是静态库而目标链接是静态库时,target_link_libraries会做啥【英文标题】:Whatdoestarget_link_librariesdowhenthetargetisastaticlibraryandthetaargetlinkisastaticlibrary当目标是静态库而目标链接是静态库时,target_link_libraries会做什么【发布时... 查看详情

typedef 结构在链接静态库时会导致名称冲突吗?

】typedef结构在链接静态库时会导致名称冲突吗?【英文标题】:Cantypedefstructurescausename***eswhenlinkingastaticlibrary?【发布时间】:2014-02-1803:01:32【问题描述】:当我创建静态库时,typedef结构会导致名称冲突吗?鉴于下面的示例头文... 查看详情

当我链接动态库而不是静态库时,CMake 有效

】当我链接动态库而不是静态库时,CMake有效【英文标题】:CMakeworkswhenIlinkadynamiclibrarybutnotastaticlibrary【发布时间】:2018-06-2301:38:00【问题描述】:当我将动态库与CMake链接时,创建make文件然后使用make,它可以正确编译和构建。... 查看详情

链接静态库时将无法识别的选择器发送到实例?

】链接静态库时将无法识别的选择器发送到实例?【英文标题】:unrecognizedselectorsenttoinstancewhilelinkingstaticlibrary?【发布时间】:2012-07-0404:23:50【问题描述】:我是这个iPhone开发的新手。现在我正在尝试开发一个静态库。我成功创... 查看详情

静态链接与动态链接

文章目录静态链接动态链接说起静态链接和动态链接,大家肯定都不陌生。静态链接与动态链接的差别顾名思义,动态链接使动态库中的函数在程序运行后,才被用到;而静态链接则在运行前,就将所需函数... 查看详情

静态链接与动态链接

文章目录静态链接动态链接说起静态链接和动态链接,大家肯定都不陌生。静态链接与动态链接的差别顾名思义,动态链接使动态库中的函数在程序运行后,才被用到;而静态链接则在运行前,就将所需函数... 查看详情

qt creator qt5.1 vs2010 使用静态库时链接器错误

】qtcreatorqt5.1vs2010使用静态库时链接器错误【英文标题】:qtcreatorqt5.1vs2010linkererrorwhenusingstaticlibrary【发布时间】:2013-09-2320:23:29【问题描述】:当我尝试在带有qt5.1的qtcreater中使用使用vs2010编译的静态库时遇到问题。我正在使用... 查看详情

链接器如何使用静态库解析引用

解析引用过程  在符号解析阶段,链接器从左到右按照它们在编译器驱动程序命令行上的出现顺序来扫描可重定位目标文件和存到文件。在这次扫描中,链接器维护一个可重定位目标文件的集合E(这个集合中的文件就是确定... 查看详情

静态链接

链接的主要任务:符号解析和重定位可重定位文件的特质:通过文件头--》探测到段表,字符串表等(结构体数组)--》从而解析整个目标文件的各个section。符号类型:定义在本目标文件的全局符号;在本目标文件引用的未定义... 查看详情

Linux:链接共享库时如何使用 .pc 文件?

】Linux:链接共享库时如何使用.pc文件?【英文标题】:Linux:howare.pcfilesusedwhenlinkingagainstasharedlibrary?【发布时间】:2010-07-2916:27:33【问题描述】:据我所知,*.pc文件存储有关共享库的元数据。链接到共享库时,链接器是否会自动... 查看详情

深入理解计算机系统链接

静态链接器以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的可以加载和运行的可执行目标文件作为输出。为了构造可执行文件,链接器必须完成两个主要任务:1、符号解析:目标文件定义和引用符号,符... 查看详情

链接器可以内联函数吗?

】链接器可以内联函数吗?【英文标题】:Canthelinkerinlinefunctions?【发布时间】:2011-08-2415:03:30【问题描述】:在文件file1.c中,调用了在文件file2.c中实现的函数。当我将file1.o和file2.o链接到一个可执行文件中时,如果file2中的函... 查看详情

链接共享库时限制符号的可见性

】链接共享库时限制符号的可见性【英文标题】:Limitingvisibilityofsymbolswhenlinkingsharedlibraries【发布时间】:2022-01-2215:42:09【问题描述】:某些平台要求您向链接器提供共享库的外部符号列表。但是,在大多数unixish系统上,这不是... 查看详情

第20课链接过程简介

1.链接器的意义(1)每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件。(2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接。 2.静... 查看详情

链接静态 C 库时 Rust 缺少库

】链接静态C库时Rust缺少库【英文标题】:RustmissinglibrarieswhilelinkingstaticClibraary【发布时间】:2020-11-0507:56:30【问题描述】:我在链接静态库时遇到了问题-当没有windows.h和对WinAPI的调用时,它链接并工作正常,但是当它们使用时... 查看详情

我可以让 gcc 链接器创建一个静态库吗?

】我可以让gcc链接器创建一个静态库吗?【英文标题】:CanIhavethegcclinkercreateastaticlibrary?【发布时间】:2010-12-2423:04:50【问题描述】:我有一个包含大约300个c++文件的库。使用该库的程序不想动态链接到它。(各种原因,但最好... 查看详情

第20课链接过程简介(代码片段)

...目标文件,这些目标文件如何生成最终的可执行程序呢?链接器: 静态链接: 静态链接就是将库文件或者目标文件直接加入到可执行文件当中。Linux下静态库的创建和使用: 静态库示例程序:20-1.c1#include<stdio.h>2... 查看详情

《程序员自我修养》阅读笔记-静态链接

静态链接分两步,(1)空间与地址分配,(2)符号解析与重定位。1空间与地址分配。空间域地址分配有两个含义,一个是输出的可执行文件的空间,一个是装载后的虚拟地址的空间。在这里我们指的是后者。在将多个目标文件... 查看详情