Can I link object files made by one compile to those made by another one?
Asked Answered
I

4

11

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.

Incontrollable answered 20/4, 2011 at 9:22 Comment(2)
What compilers are you using?Cyan
Well, for the framework GCC. What will the programmer use is his choice and I need to know if I have to warn him ot not.Incontrollable
C
11

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

This document was developed jointly by an informal industry coalition consisting of (in alphabetical order) CodeSourcery, Compaq, EDG, HP, IBM, Intel, Red Hat, and SGI...

In this document, we specify the Application Binary Interface for C++ programs, that is, the object code interfaces between user C++ code and the implementation-provided system and libraries. This includes the memory layout for C++ data objects, including both predefined and user-defined data types, as well as internal compiler generated objects such as virtual tables. It also includes function calling interfaces, exception handling interfaces, global naming, and various object code conventions.

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.

Cyan answered 20/4, 2011 at 9:26 Comment(5)
@anatolyg: see my edit. g++ has supported the industry standard C++ ABI since version 3. see: codesourcery.com/public/cxx-abi/abi.htmlCyan
I target all platforms where GCC and JVM can be found - including Windows with MSVC as the second compiler. However, mainly used compiler should be GCC.Incontrollable
@Rusty Horse: Windows uses a different object file format than Linux, so you'll probably need a separate object file for the two platforms.Cyan
Of course. Framework will be compiled on each target platform by GCC.Incontrollable
There is a standard C++ binary API for the Itanium. There is not for most other systems: you cannot link C++ code compiled with g++ to that compiled with Sun CC under Solaris, for example, and you cannot link C++ code compiled with g++ to that compiled with VC++ under Windows. Very often, in fact, you cannot link C++ code compiled with one version of a compiler to that compiled with an earlier version.Geulincx
D
7

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.

Deputize answered 20/4, 2011 at 9:27 Comment(1)
There is an industry standard C++ ABI which has been the default in gcc since version 3. How widely implemented it is I'm not sure, but the standard does exist and is supposedly backed by at least: CodeSourcery, Compaq, EDG, HP, IBM, Intel, Red Hat, and SGICyan
M
2

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.

Mireille answered 20/4, 2011 at 9:26 Comment(3)
Ok, and how can I check that? Where can I find such information?Incontrollable
Well, for example for gcc, google is your friend.Mireille
There is a lot more than the instructions set and the object file format to take into account, especially for C++.Deputize
G
0

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 (including things 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 and std::string, chosen according to compiler options.

Geulincx answered 20/4, 2011 at 11:9 Comment(4)
That's interesting, so you're saying that in practice it's not enough to target the same instruction set, object file format and ABI standard? How do you account for dll's ( on Windows ) and shared object files on Linux that can be used from a variety of compilers? I used to ( years ago ) compile dll's in Borland Builder and then use them in Visual Studio and visa versa... If object files from one compiler could never be linked to object files from another compiler you'd basically only have one C++ compiler allowed on any particular platform.Cyan
@Robert: GCC uses a slightly different format (among others, the name mangling is different) and is thus incompatible with Visual C++ toolchains. If Borland builder worked as you say it does, I assume it either used the Visual C++ linker, or conformed to exactly the same ABI/object file format. Not being able to mix object files does not mean that different toolchains can't create usable binary files with a different kind of intermediate step (=object files).Erde
@Robert Targetting the same ABI standard is only valid if that standard exists (which is not the case for most systems), and if it covers everything you're doing (e.g. the implementation of std::vector, if you're using std::vector). About all that you usually get is an ABI standard which covers C, and even then, there are often compiler options which break this.Geulincx
Note that in the case of DLL's, there are usually ways (mostly active by default under Windows) of masking everything in the DLL except what you explicitly export. If what you explicitly export is covered by the ABI specification (usually, just pure C), then you can link DLL's compiled with different compilers. Firefox, for example, doesn't impose any specific compiler for its plugins. But you have to design and build the application with this in mind.Geulincx

© 2022 - 2024 — McMap. All rights reserved.