Delphi可以输出.obj文件,但它们是Intel OMF的32位变体。另一方面,GCC使用ELF(Linux、大多数Unix系统)、COFF(在Windows上)或Mach-O(Mac)。
但这还不足够。没有使用运行时库很难编写大量代码,而运行时库的实现将依赖于编译器和链接器体系结构的低级细节,例如正确的初始化顺序。
此外,与对象文件格式相比,兼容性还有更多的要素; 特别是在Linux上的代码需要是位置无关的,这意味着它不能使用绝对值来引用全局符号,而必须从寄存器或相对于指令指针索引其所有全局数据,以便该代码可以在内存中重定位而不需要重写引用。
DCU文件是Delphi符号表和为每个过程生成的代码的序列化,因此高度依赖于编译器的实现细节,而这些细节会随着版本的更改而发生变化。
所有这些意味着,除非您限制自己使用最少量的非托管数据类型(没有字符串、没有接口)和过程代码(没有类、没有初始化部分、没有需要初始化的数据等),否则您很难将Delphi (dcc32)代码链接到GNU环境中。
为了更好地理解,您需要知道Delphi的.dcu文件可以转换为两个不同的FPC文件,.ppu文件包含所述的符号表信息,其中包括内联函数和通用定义等不可链接的代码,而.o文件在Windows上与mingw兼容(COFF)。Cygwin在链接级别上也兼容mingw(但运行时不同且令人害怕)。无论如何,mingw32/64是我们在Windows上参考的gcc。
PPU与Delphi的DCU有类似的版本问题,可能是出于相同的原因。ppu格式在每个主要版本发布时几乎都不同。(例如2.0、2.2、2.4),并且通常每年在trunk中更改2-3次
因此,尽管FPC在Windows上使用自己的汇编器和链接器,但它生成的.o文件仍与mingw32兼容。总体而言,FPC的输出非常与gcc兼容,通常可以直接链接gcc静态库,允许将mysql和postgres链接库与适当许可证(如GPL)的应用程序链接起来。 在64位上它们也应该兼容,但这可能比win32测试得少。
文本模式IDE甚至以库形式链接整个GDB调试器。 GDB是Windows上gcc兼容性的主要原因之一。
虽然Barry关于运行时的一般观点也适用于FPC,但解决这个问题可能会稍微容易一些。它可能只需要从启动代码中调用某些函数来初始化FPC rtl,并对finalize进行类似的操作。使用-al编译最小的FPC程序并查看生成的汇编程序(在.s文件中,特别是initializeunits和finalizeunits)此外,RTL更灵活,可能更容易缩小到最小。
当然,一旦您还需要跨gcc<->fpc边界使异常工作,您就没有机会了。 FPC不使用SEH或任何与ATM兼容的方案。(与Delphi相反,Delphi使用SEH,在理论上应该在这方面给您一个优势,Barry?)另一方面,gcc可能使用自己的libunwind而不是SEH。
请注意,x86上FPC的默认调用约定与Delphi兼容的寄存器,因此您可能需要插入正确的cdecl(应该与gcc兼容)修饰符,甚至可以使用{$calling cdecl}为整个单位设置。
在*nix上,这是标准的(例如apache模块),但我不知道有多少人在win32上这样做。
关于兼容性;FPC可以编译像Indy、Teechart、Zeos、ICS、Synapse、VST等包,几乎不需要进行修改。发布版本的方言级别是D7及以上的混合,重点是D7。方言级别正在缓慢地向D2006级别移动(具有for in、class abstract等)
由于DCU格式是专有的,并且往往会在Delphi的不同版本之间发生变化,因此可能没有可靠的方法将DCU转换为OBJ。最好的方法是按照Andreas的答案,在第一次构建时就使用OBJ格式。