(C/C++)如何生成可在Windows和Linux上运行的可执行文件?

9 c c++ linux windows cross-platform

我是编程新手.据我所知,在Linux中编译的程序不应该能够在Windows中运行.因此,如果我们想在两个平台上运行相同的程序,我们需要在两个平台下编译源代码,并创建2个不同的可执行文件.

最近我正在研究开源,跨平台Java GUI应用程序的源代码.我很惊讶地发现该GUI应用程序的后端引擎是一个由C++代码生成的小型可执行文件.无论用户在Windows或Linux中使用该应用程序,Java GUI都将在bin文件夹中调用相同的可执行文件.

我只是想知道,该可执行文件如何在Windows和Linux上运行?

我也有兴趣使用C++程序作为引擎创建一个跨平台的Java GUI应用程序.该C++程序仅适用于Linux.我已经谷歌搜索了一段时间,我发现我需要使用Cygwin将其移植到Windows.但是,如果我使用Cygwin,我将最终拥有2个不同的可执行文件.

如何将Windows可执行文件与Linux可执行文件组合?是否可以生成可在两个平台上运行的单个可执行文件?

谢谢.

小智 10

简单的答案是,你不能.

PE(Windows)和ELF(Linux)二进制可执行格式完全不同.

更不用说C/C++程序需要链接到同时在任一平台上都不可用的库.

但是,您可以在Linux上使用Wine来运行Windows可执行文件,前提是它不会尝试异乎寻常的Windows特定调用.

或者您可以选择使用更常见的跨平台语言,例如.NET语言(C#/ IronPython/Java等),.NET for Windows和Mono for linux/Others支持.


Dav*_*nan 8

没有办法从C++源编译一个可在不同平台上运行的单个本机可执行文件.我不相信你在Windows和Linux上运行相同的可执行文件,正如你在第二段中所述.


小智 8

好的,孩子们。

是的,您可以编写多平台二进制文件,但这很困难。它被称为 Fat Binary,它在 1980 年代曾经很常见,尽管我已经有几十年没有见过它了。https://en.wikipedia.org/wiki/Fat_binary

基本上,您为要运行的每个平台编译机器代码,然后将代码与不同的入口点手动链接。虽然维基百科的文章只是描述了将不同的体系结构打包到同一个二进制文件中,但实际上可以制作一个在不同操作系统上运行的二进制文件,只要操作系统的入口点不冲突。

一些可执行格式被有意设计为允许这样做。例如,可以叠加 MZ、NE、LX 和 PE。旧的 OS/2 程序有时会这样做……它们很少包含适用于两个操作系统的整个程序,但是在 DOS 上运行时会打印一条消息,告诉您您正在为该程序使用错误的操作系统。

至于 Linux 和 Windows 在一个二进制文件中:虽然你不能做 ELF 和 PE,但我相信它可能可以用 PIE 或 COFF 和 PE 或 COM。较旧的 Linux 将运行 COFF 二进制文件,它是 PE 的后代,因此如果较新版本的 Linux 仍能运行这些二进制文件,您似乎可以创建通用二进制文件。我不能肯定地说这会奏效,但它似乎是合理的。

另一个警告:通常您需要在代码开始时跳转,以跳过其他操作系统的入口点、标题等,因为您无法在那里找到您的代码(显然)。

这在现代计算中的问题在于,大多数防病毒软件会错误地将其识别为病毒。过去,病毒通常会通过在可执行文件的开头插入这样的跳转来攻击二进制文件,该跳转跳转到二进制文件的末尾,将自己的代码添加到二进制文件的末尾,然后插入另一个跳转回主可执行文件代码。由于您需要做一些或多或少类似于在一个二进制文件中支持多个平台的事情,因此大多数 AV 软件会启发式地将其识别为病毒并隔离您的可执行文件。

简而言之:是的,它可以用于(某些)平台组合。这并非不可能,但你必须疯了才能做到。

  • 实际上已经有人去做了这件事。这是否意味着贾斯汀疯了@NoDeadCode?=)https://github.com/jart/cosmopolitan (3认同)