【问题标题】:if we had a single file project that contained all the code can we not use the linker?如果我们有一个包含所有代码的单个文件项目,我们可以不使用链接器吗?
【发布时间】:2021-03-16 12:26:56
【问题描述】:

链接器问题:

如果我有一个文件。 c 根本没有包含,我们还需要链接器吗?

【问题讨论】:

  • 是的,除非您打算自己重新实现 C 和 C++ 库中的每个类、模板和函数。
  • 很可能你仍然需要它。您需要链接到运行时库才能正常输入和输出。
  • 目标文件格式不是 ELF/EXE/Whatever。链接器负责创建适当的可执行格式。
  • 是的。在“编译然后链接”构建链中,编译器通常输出不是可执行格式的目标文件。即使源文件不依赖头文件,也需要链接器将目标文件转换为可执行格式。唯一的区别是链接器可以将多个目标文件和库中的函数链接在一起(例如,将调用函数的每个点链接到被调用函数的开头)以生成单个可执行文件。

标签: c++ c embedded


【解决方案1】:

虽然链接器之所以如此命名是因为它将多个目标文件链接在一起,但它也执行其他功能。它可能会解析编译器留下的不完整地址。它以系统的程序加载器可以读取和加载的可执行文件格式生成程序,并且该格式可能与目标模块的格式不同。具体取决于操作系统和构建工具。

此外,要在一个源文件中拥有完整的程序,您不仅必须提供您在 C 和 C++ 中熟悉的 main 例程,还必须提供程序的真正启动,即程序加载器启动的入口点执行,并且您必须为您在程序中使用的所有功能提供实现,例如通过特殊陷阱或系统调用指令调用系统服务以读取和写入数据。

【讨论】:

  • 所以我接受它:如果我制作了一个 file.c,其中包括 1- 主函数 2-. 我所做的每个函数调用的主体 3- 将导致主函数的启动代码最终 4-必须包含的所有内容,我不知道我仍然需要链接器来完成将 file.obj 传输到 file.exe 或 hex 或任何东西的工作
  • 这个问题和这个答案让我想起了this 博客文章,其中讨论了直接加载和执行目标文件。 tl;dr:这是可能的,但你必须手动做很多事情,而不是依赖加载器。
  • @AliHamdy,IMO 这篇博文并不重要,因为parseObject 的存在表明链接器是不可避免的。将链接器的工作转移到自定义对象解析器中只是混淆了这一点。
【解决方案2】:

您可以创建一个没有典型 C 启动代码的项目,在这种情况下,您甚至可能没有main()。但是,您仍然需要一个链接器,因为链接器会为给定的架构创建所需的可执行文件格式。

它还将设置实际执行开始的入口点。 所以你可以省略标准库,创建一个完全没有任何 C 函数的二进制文件,但你仍然需要链接器来实际生成一个可运行的二进制文件。

编译器生成的目标文件格式与可执行文件格式非常不同,因为它只提供链接器所需的所有信息。

【讨论】:

    【解决方案3】:

    是的。链接器不仅仅链接文件。查看此资源以获取更多信息:https://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Compiler/Linker#:~:text=The%20linker%20is%20a%20program,translation%20unit%20have%20external%20linkage

    信不信由你,默认情况下可以引用多个库。因此,即使您没有#includea 资源,编译器也可能必须在内部链接或引用翻译单元之外的内容。编译器还“消除”了冗余和其他注意事项。

    【讨论】:

      【解决方案4】:

      尽管它的名字链接器是正确的“链接器/定位器”。它执行两个功能 - 1) 链接目标代码,2) 确定数据和代码元素在内存中的位置。

      即使没有未解析的链接,编译器输出的目标代码也不会“定位”。

      即使你有最简单的有效代码:

      int main(){ return 0; }
      

      如果不包含,链接器通常会隐式链接 C 运行时启动,这是在运行main() 之前执行所有必要的操作所必需的。那可能很少。在某些目标(例如 ARM Cortex-M)上,您实际上可以直接从复位向量运行 C 代码,只要您不假设静态初始化或完整的库支持。因此,可以完全用 C 语言编写重置代码,但您可能仍需要使用重置处理程序(您的 C 启动函数)和初始堆栈指针来初始化向量表的代码。在 Cortex-M 上,也许可以使用内联汇编器来完成,但这一切都相当麻烦和不必要,并且不会放弃链接器。

      【讨论】:

        猜你喜欢
        • 2021-08-23
        • 2019-11-08
        • 2019-11-28
        • 2019-06-09
        • 2021-10-11
        • 1970-01-01
        • 2017-05-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多