It is possible to create Windows executables on a Linux build machine by using a cross-compiler. But, Intel does not provide such cross compilers.
To answer the sub-questions:
What are the object file formats of gcc, g++, cl, mingw32, icc, icpc, and icl on Windows and Linux (current versions)?
The format for the object files is effectively determined by the operating system (or rather, the compiler used to build it). For Windows, this is the Portable Executable (PE) format and for Linux the ELF format.
Could parts of the mingw32 cross-compiler toolchain be used to accomplish the goal?
No. The relevant part is the code generator, which is both the part responsible for generating the right object format and the part on the Intel compilers that gives their generated code the speed edge.
Am I right that the metadata in the generated object files is the main issue?
No. It is one issue, but there are more. A more fundamental problem is the potential difference in how parameters are passed to the kernel and/or standard library. IIRC, those conventions are different between Windows and Linux.
The general answer is no, C language compilers are not compatible with each other. The C language standard does not define any kind of binary interoperability, and most compiler writers don't even try.
I need to qualify that. The objects emitted by a C compiler have to be linked with runtime libraries to produce either an executable or a runtime linkable library. Although the visible functions provided by the C runtime library should be compatible, there will also be non-visible functions that are unique to the implementation and prevent interoperability.
This lack of compatibility also extends to different versions of the same compiler. In general, programs and libraries compiled with older and newer versions of a compiler cannot be linked together, and those compiled with MSVC cannot be linked with those compiled by GCC.
There is a specific and very useful exception. Every platform provides a dynamic linking ABI (Application Binary Interface) and any program in any language that can conform to that ABI is compatible. Therefore it is generally possible to build a DLL (on Windows) with MSVC (or something else) and call it from a program compiled by a different version of MSVC or by GCC and vice versa.
There are two other ABIs on Windows: COM and .NET assemblies, and they span a wide range of languages. So interoperability is definitely possible, but compatible they are not.
The degree of incompatibility can easily be seen by comparing the linker maps. For GNU use ld -M
, for MSVC use link /map
. Study the two generated files. Both will have names in them that you recognise, such as printf and main, although (depending on options) the names are likely to be mangled in various ways. They will also have names that are completely different, many of which you won't recognise. In order for object files produced by different compilers to be compatible they have to agree on all those names, and they never do. Not even different versions of the same compiler can always do that.
Best Answer
First of all, it's really hard for any non-trivial program to 'not require any other library'. Remember that glibc and the startup code calling
main()
are libraries too.But yes, even in this case you need the linker, just because the compiler/assembler typically don't handle ELF format (or any executable format). Precisely because usually you'll have to link with some libraries, so why should it bother to compile to ELF? It's better to focus on linkable-code formats and leave the executable formats to the linker.
PS: I forgot that
.so
is also a variant of ELF. But it still doesn't change the fact that it's a different subformat and the executable details are just not included in most compiler/assembers.Yes, it's quite possible for a single tool to compile directly to executable, but that just means that it includes both the compiler and the linker in a single command. Why would it consider the (very) special case when you won't add any other code? It's far more logical to do it in the linker, after all you'll need it in %99.9 cases.