我可以将一个编译生成的目标文件链接到另一个编译的目标文件吗?

Rus*_*rse 9 c++ compiler-construction linker object-files

更具体地说,假设两个编译器都在同一平台上(OS +指令集).但是,其中一个目标文件是由依赖于编译器的代码构成的.另一方面 - 代码是面向对象的并且尊重封装.

我需要这个用于我正在制作的一种框架.目标平台是GCC和Java虚拟机的任何系统.实际上,该框架将在每个平台上编译.使用框架用户的编译器取决于他.

Rob*_*nes 10

只要它们使用相同的目标文件格式并以同一机器指令集为目标,您就应该能够链接它们.例如,假设您有两个C编译器,每个编译器都有自己的专有语言扩展.您编译两个不同的文件,一个使用编译器A,另一个使用编译器B.每个源文件都使用它各自编译器的语言扩展.只要两个编译器都设置为针对相同的平台和体系结构,例如Linux上的i386指令集,那么您应该能够将文件链接到一个可执行文件中.

在wiki上查看此目标文件格式列表.

您可能也对此感兴趣:

用于探索目标文件的UNIX工具

编辑

根据这篇文章" C++标准库ABI ",有一个行业标准C++ ABI,您应该能够链接任何符合此标准的编译器的对象文件.你可以在这里看到标准:

安腾C++ ABI

本文档由一个非正式的行业联盟共同开发,该联盟由(按字母顺序)CodeSourcery,Compaq,EDG,HP,IBM,Intel,Red Hat和SGI组成......

在本文档中,我们为C++程序指定了应用程序二进制接口,即用户C++代码与实现提供的系统和库之间的目标代码接口.这包括C++数据对象的内存布局,包括预定义和用户定义的数据类型,以及内部编译器生成的对象,如虚拟表.它还包括函数调用接口,异常处理接口,全局命名和各种目标代码约定.

因此,只要您定位相同的指令集,目标文件格式并使用标准C++ ABI(现在是gcc/g ++中的默认值),您应该没问题,当然假设标准C++ ABI实际上是标准的并且正确实现大多数在Linux上运行的现代C++编译器(这似乎是你所针对的平台).

编辑2

你应该看看这篇SO帖子:

GCC与MS C++编译器,用于维护API向后二进制兼容性

看起来微软并没有遵循任何关于他们的C++ ABI的一致标准(Itanium或其他),所以如果你使用gcc编译Windows,它可能会成为一个问题.

您可能还想看看这两篇文章:

C++的策略/二进制兼容性问题

对二进制兼容性的一些看法

您可以将用户限制为支持Itanium ABI的编译器,但这取决于您的目标受众.

  • Itanium有一个标准的C++二进制API.大多数其他系统都没有:例如,您无法将使用g ++编译的C++代码链接到使用Sun CS编译的C++代码,并且无法将使用g ++编译的C++代码链接到使用Windows下的VC++编译的代码.实际上,您经常无法将使用一个版本的编译器编译的C++代码链接到使用早期版本编译的代码. (2认同)

APr*_*mer 7

这取决于编译器.有些使用相同的ABI,因此生成可以链接在一起的对象,有些则没有,对象也无法链接.通常 - 事实上,我也不例外 - 当编译器使用不兼容的ABI时,它们也使用不兼容的名称修改并且链接阶段失败.

实际上,需要相当多的努力和协调才能将用不同编译器构建的对象链接在一起.曾经有一段时间经常在两个不同版本的gcc之间无法实现.

ABI中的名称比名称更多:

  • 精确的对象布局(包括填充,vtable的格式和RTTI信息的格式,......)

  • 例外的方式

  • 返回结果的方式

  • 传递参数的方式(在寄存器中或不在寄存器中,哪些寄存器,在哪里this)

  • 谁保存了不用于结果/参数的寄存器(调用者,被调用者......)

  • 模板的处理方式(例如静态数据成员)

  • 使用的标准库版本

  • ...

为了了解ABI的复杂性,这里有一个文档详细描述了Itanium上使用的ABI.IIRC,它是对描述C ABI的类似文件的补充.它通过gcc在其他目标上使用(对于非机器相关部件).