我可以将一种编译生成的目标文件链接到另一种编译生成的目标文件吗?
更具体地说,我们假设两个编译器位于同一平台(操作系统+指令集)上。然而,其中一个目标文件是由依赖于编译器的代码生成的。另一方面 - 代码是面向对象的并且尊重封装。
我需要这个来构建我正在制作的框架。目标平台是任何有GCC和Java虚拟机的系统。事实上,该框架将在每个平台上编译。使用框架的编译器由用户决定。
To be more specific, lets assume that both compilers are on the same platform (OS + instruction set). However, one of the object files was made from a compiler-dependent code. On the other hand - the code is object oriented and respects encapsulation.
I need this for a kind of a framework I am making. Target platform is any system where is GCC and Java Virtual Machine. Indeed the framework will be compiled on each platform. The compiler which use the framework user is up to him.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只要它们使用相同的目标文件格式并针对相同的机器指令集,您就应该能够链接它们。例如,假设您有两个 C 编译器,每个编译器都有自己的专有语言扩展。您编译两个不同的文件,一个使用编译器 A,另一个使用编译器 B。每个源文件都使用其各自编译器的语言扩展。只要两个编译器设置为针对相同的平台和体系结构,例如 Linux 上的 i386 指令集,那么您应该能够将文件链接到一个可执行文件中。
查看 wiki 上的对象文件格式列表。
您可能也会对此感兴趣:
用于探索目标文件的 UNIX 工具< /a>
编辑
根据本文,“C++ 标准库 ABI",有一个行业标准 C++ ABI,您应该能够链接任何符合此标准的编译器的对象文件。您可以在此处查看该标准:
Itanium C++ ABI
因此,只要您针对相同的指令集、目标文件格式并使用标准 C++ ABI(现在是 gcc / g++ 中的默认值),就应该没问题,当然假设标准 C++ ABI 实际上是标准的并且正确实现由大多数在 Linux 上运行的现代 C++ 编译器提供(这似乎是您的目标平台)。
编辑2
你应该看看这个帖子:
GCC 与 MS C++ 编译器用于维护 API 向后二进制兼容性
似乎 Microsoft 没有遵循任何关于其 C++ ABI 的一致标准(Itanium 或其他),因此如果您使用gcc for Windows 可能会成为一个问题。
您可能还想查看这两篇文章:
C++ 的策略/二进制兼容性问题
关于二进制兼容性的一些想法
你可以将您的用户限制为支持 Itanium ABI 的编译器,但这取决于您的目标受众。
You should be able to link them as long as they use the same object file format and target the same machine instruction set. For example, say you have two C compilers each with it's own proprietary language extensions. You compile two different files, one with compiler A the other with compiler B. Each source file uses language extensions of it's respective compiler. As long as both compilers are set to target the same platform and architecture, for example i386 instruction set on Linux, then you should be able to link the files into one executable.
See this list of object file formats on wiki.
This might also be of interest to you:
UNIX tools for exploring object files
EDIT
According to this article, "C++ Standard Library ABI", there is an industry standard C++ ABI and you should be able to link objects files of any compiler which conforms to this standard. You can see that standard here:
Itanium C++ ABI
So as long as you target the same instruction set, object file format and use the standard C++ ABI ( which is now the default in gcc / g++ ) you should be ok, assuming of course that the standard C++ ABI is actually standard and properly implemented by most modern C++ compilers that run on Linux ( which seems to be the platform you're targeting ).
EDIT 2
You should take a look at this SO post:
GCC vs MS C++ compiler for maintaining API backwards binary compatibility
It seems like Microsoft doesn't follow any consistent standard ( Itanium or otherwise ) regarding their C++ ABI, so if you compile with gcc for Windows it likely is going to be a problem.
You probably also want to look at these two articles:
Policies/Binary Compatibility Issues With C++
Some thoughts on binary compatibility
You could restrict your users to compilers which support the Itanium ABI, but that depends on your target audience.
这取决于编译器。有些使用相同的 ABI 并因此生成可以链接在一起的对象,有些则不这样做对象无法链接。通常——事实上,我知道没有例外——当编译器使用不兼容的 ABI 时,它们也会使用不兼容的名称修饰,并且链接阶段会失败。
事实上,需要付出相当大的努力和协调才能将使用不同编译器构建的对象链接在一起。曾经有一段时间,两个不同版本的 gcc 之间通常是不可能的。
ABI 中除了名称修改之外还有很多内容:
对象的精确布局(包括填充、vtable 的格式和 RTTI 信息的格式,...)
异常的携带方式
返回结果的方式
参数传递方式(是否在寄存器中,哪个寄存器,
this
在哪里)谁保存不用于结果/参数的寄存器(调用者、被调用者,...)
处理模板的方式(例如静态数据成员)
使用的标准库版本
...
为了了解 ABI 的复杂性,这里是一份文档,详细描述了 Itanium 上使用的 ABI。 IIRC,它是对描述 C ABI 的类似文档的补充。 gcc 在其他目标上使用它(用于非机器相关部分)。
It depends on the compilers. Some are using the same ABI and thus generate objects which can be linked together, some don't and the objects can't be linked. Usually -- in fact, I know of no exception -- when compilers are using incompatible ABI, they are also using incompatible name mangling and the link phase fails.
In fact, one need quite a lot of effort and concertation for being able to link together objects built with different compilers. There was a time when often it wasn't possible between two different versions of gcc.
There is quite a lot more in the ABI than the name mangling:
precise layout of objects (included padding, the format of the vtable and the format of RTTI info,...)
the way exceptions are carried on
the way results are returned
the way parameters are passed (in registers or not, which registers, where is
this
)who save the registers which don't are used for result/parameter (the caller, the callee, ...)
the way templates are handled (static data members for instance)
the standard library version used
...
To give an idea of the complexity of an ABI, here is a document which describes in details the ABI used on Itanium. IIRC, it is an addition over a similar document describing the C ABI. It is used (for the non machine dependent parts) by gcc on other targets.
是的。
编译后,目标文件仅包含不依赖于编译器的明确定义的目标代码,即使源文件使用依赖于编译器的代码也是如此。
确保您使用相同的对象格式,但您已经知道使用相同的指令集,所以不必担心。
Yes.
Once compiled the object file only contains well-defined object code that do not rely on compiler, even though the source file used compiler-dependent code.
Make sure you use the same object format, but you already know the same instruction set is used, so don't worry about that.
简单的答案是否定的。可以链接两个目标文件
仅当它们二进制兼容时才在一起。 (更正确地说
声明:可能也可能不可能将它们链接在一起,但是
即使它们链接,生成的程序也将无法工作。)
意味着它们以相同的方式传递参数(对于所有类型
参数),以相同的方式传递任何隐藏参数(例如
this
),以相同的方式布置所有数据结构(包括你看不到的东西,比如 vtable),以及所有的类和
两个目标文件使用的对象具有相同的定义。
这通常适用于 C,因为大多数(如果不是全部)平台
为 C 指定一个二进制 API。这几乎不适用于 C++,
因为几乎没有平台指定二进制 API
C++——一个值得注意的例外是 Itanium,它是
规范要么不完整,要么不被尊重。在
实践中,其实不仅要使用相同的
编译器,但你必须使用相同的编译代码
选项:例如,g++ 和 VC++ 都有两种不同的选项
诸如
std::vector
之类的不兼容实现std::string
,根据编译器选项选择。The simple answer is no. Two object files can be linked
together only if they are binary compatible. (More correctly
stated: it may or may not be possible to link them together, but
even if they link, the resulting program won't work.) This
means that they pass parameters in the same way (for all types
of parameters), pass any hidden arguments in the same way (e.g.
this
), lay out all data structures in the same way (includingthings you don't see, like the vtable), and that all classes and
objects used by the two object files have the same definition.
This works for C, usually, because most, if not all platforms
specify a binary API for C. This almost never works for C++,
because almost no platform specifies a binary API for
C++—the one notable exception is the Itanium, and it's
specification is either incomplete, or not respected. In
practice, in fact, not only do you have to use the same
compiler, but you have to compile the code with the same
options: both g++ and VC++, for example, have two different
incompatible implementations for things like
std::vector
andstd::string
, chosen according to compiler options.