通过将静态构建转换为特定于操作系统的二进制文件来跨操作系统构建

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

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

我在理解静态构建时的陷阱是什么? 这是否意味着它消除了对第 3 方和标准以及操作系统库和 header 的任何需求?! 为什么我们不能删除例如 ELF 的 meta 并放入 PE 所需的 meta 和其他规范?

提及: 我说,跨操作系统不是跨硬件

[阅读下文后阅读!] 正如您看到的最佳答案,到现在为止(!)继续学习跨平台开发问题!!!这有多疯狂?!感谢哲学!!!

最佳答案

我会说这是可能的,但这个过程必须被许多细节削弱。

ABI 兼容性

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

标准库

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

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

操作系统特定的寄存器使用

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

虚拟地址

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

因此,虽然理论上可行,但这种转换在实际情况下一定非常脆弱,并且不可能重新植入整个静态构建代码 - 有些部分可能会原封不动地转移,但必须重新链接到与其他系统交互的特定于系统的代码内核正确。

附言我想Wine是在完全不同的系统上运行二进制代码的一个很好的例子。它欺骗 Windows 程序认为它在 Windows 环境中运行并使用相同的机器代码 - 大多数情况下运行良好(如果程序不使用私有(private)系统低级例程或不可用的库)。

关于通过将静态构建转换为特定于操作系统的二进制文件来跨操作系统构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21710722/

相关文章:

C 使用 fork() 共享内存

c++ - 虚拟内存或物理内存

c - 如何处理二进制数据中的 Windows/Unix EOF 警告?

c++ - 使用 C++ 进行跨平台 GUI 开发

flutter - 将 Flutter 用于社交媒体平台的移动和网络是否可行?

android - ionic 标签 : content not fitting when changing platform

linux - 链接错误: undefined reference to static libarary

c++ - gcc ld : method to determine link order of static libraries

c++ - 消除 C++ 动态库的编译器间不兼容问题

从 glade 克隆一个 GtkWidget,这样它就可以在应用程序中多次重用