通过将静态bulid转换为os特定二进制来构建跨os

时间:2014-02-11 19:00:30

标签: c cross-platform static-linking elf portable-executable

是否有可能在C中编写代码,然后静态构建它并像ELF / PE一样从中创建二进制文件然后删除其标题和所有不必要的元数据,以便创建原始二进制文件,最后能够把这个原始二进制文件放在任何其他类型的操作系统中,如(ELF> PE)或(PE> ELF)?! 你以前做过吗? 可能吗? 什么是问题和关注? 怎么可能这样?! 如果没有,请告诉我为什么不呢?!!?!

我对理解静态构建有什么缺陷? 这是否意味着它不再需要第三方和标准以及os libs和标题?! 为什么我们不能删除例如ELF的元数据并放置PE所需的元数据和其他规范?

提及:     我说,Cross OS不是Cross Hardware

[阅读下面阅读!] 当你看到最好的答案时,到现在为止(!)继续学习跨平台开发问题!这有多疯狂?!感谢哲学!!!

1 个答案:

答案 0 :(得分:1)

我想说这是可能的,但这个过程必须被很多很多细节所摧毁。

ABI兼容性

首先要考虑的是应用程序二进制接口兼容性。除非您能够以相同的方式调用您的函数,否则代码将被破坏。所以我想(虽然我目前无法检查)在Linux / OS X上使用gcc编译代码和Windows上的MinGW gcc应该提供相同的二进制代码,只要没有调用外部函数。这里的问题是可执行元数据可能依赖于某些ABI假设。

标准库

这似乎是最大的障碍。部分原因在于C预处理器可以在某些平台上内联某些程序,使其在其他平台上运行。此外,与标准库的跨平台动态互操作几乎是不可能的,但理论上可以想象一个代码使用在不同平台上通过相同ABI公开的C标准库的有限子集。

静态构建主要消除了与其他用户空间代码交互的问题,但是仍然存在与内核接口的巨大问题:它在x86 Linux上调用int $0x80和在特定于平台的系统调用数字集不以任何直接方式映射到Windows。

特定于OS的寄存器

据我所知,Windows使用寄存器%fs存储一些操作系统范围的异常处理内容,因此在Linux上编译的二进制文件应避免使其混乱。可能还有其他类似的问题。此外,Windows上的C ++异常主要是通过操作系统异常完成的。

虚拟地址

同样,AFAIK Windows DLL具有一些预定义的地址,它们必须加载到进程的虚拟地址空间中,而Linux使用与位置无关的代码用于共享库。因此,可执行文件和移植代码的重叠区域可能存在问题,除非移植的位置相关代码被重新编译为与位置无关。

因此,虽然理论上可行,但这种转换在实际情况下必须非常脆弱,并且不可能重新构建整个静态构建代码 - 某些部分可能完整地传输,但必须重新链接到与其他部分连接的系统特定代码内核正确。

P.S。我认为Wine是在完全不同的系统上运行二进制代码的一个很好的例子。它试图让Windows程序认为它在Windows环境中运行并使用相同的机器代码 - 大部分时间都运行良好(如果程序不使用私有系统低级例程或不可用的库)。