【问题标题】:How can I make a portable executable?如何制作可移植的可执行文件?
【发布时间】:2010-11-03 11:11:08
【问题描述】:

有没有办法编译 c/c++ 源文件以输出可以在不同计算机上的其他处理器上运行的 .exe 文件? 我问这个用于 Windows 平台。 我知道它可以用 java 或 c# 完成,但它使用虚拟机。

PS: 对于那些说只能用虚拟机或必须在每台机器上编译源代码的人,我问的是所有病毒都是用java还是c#编写的,你需要一个vm机器才能被感染或者你需要在你的机器上编译蠕虫的源代码才能被感染? (我不是想制造病毒,而是一个很好的例子:))

【问题讨论】:

  • 操作系统是否相同?这就是问题所在。
  • 必须.exe 隐含COFF,或者它可以是ELF 或任何其他二进制格式?那是另一个问题...
  • 是的,相同的操作系统(在本例中为 Windows)。

标签: c++ c executable portability


【解决方案1】:

不同的计算机使用不同的指令集、操作系统系统调用等,这就是机器代码是特定于平台的原因。这就是为什么已经开发了各种技术(如字节码、虚拟机等)以允许可移植的可执行文件。但是,通常 C/C++ 直接编译为特定于平台的机器代码。

因此,如果没有某种模拟层,Windows exe 根本无法在另一个平台上运行。

但是,您可以使您的 C/C++ 源代码可移植。这意味着要让您的应用程序在另一个平台上运行,您需要做的就是为该平台编译它。

【讨论】:

    【解决方案2】:

    是的,你可以,但这不一定是个好主意。

    Apple 在 90 年代初从摩托罗拉 68000 迁移到 PowerPC 芯片时引入了fat binary 的想法(我并不是说他们发明了它,这只是我所知道的最早的化身)。该链接还描述了 FatELF Linux 通用二进制文件,但鉴于我们对它们的了解很少,它们似乎还没有流行起来。

    这是一个单独的文件,基本上包含捆绑到一个文件中的 68000 和 PowerPc 可执行文件,并且需要操作系统的一些智能,以便它可以加载和执行相关的。

    如果你愿意,你可以编写一个编译器,生成一个可以在很多平台上运行的胖二进制文件,但是:

    • 它会大得吓人;和
    • 几乎可以肯定,每个目标系统都需要特殊的加载器。

    既然gcc 对不同平台和交叉编译有如此多的支持,那将是我集中精力的地方,我是否疯狂尝试:-)

    【讨论】:

    • 苹果仍然这样做。 “通用二进制文件”包含 PPC 和英特尔二进制文件。编辑:虽然它不是一个真正的二进制文件,但不同的二进制文件(和图标之类的元数据)包含在具有“应用程序”扩展名的目录中。
    • 人们可能会考虑使用 clang,尽管它非常不发达,并且可能需要将 clang 与二进制文件一起发送?
    • @Matt Joiner,clang 是编译器,llvm 是运行时。
    【解决方案3】:

    简短的回答是 - 你不能。更长的答案是用可移植(标准)C/C++ 编写并在您需要的平台上编译。

    【讨论】:

    • 不,更长的答案是您可以,但您可能不想这样做。 (例如编译成 Java 字节码。)
    • @Amigable 许多平台不存在 JVM,但有兼容的 C 编译器。
    • 这个“长答案”没有回答同一个问题。它询问的是如何制作在多个平台上运行的单个二进制文件,而不是如何从单个源编译多个平台。
    【解决方案4】:

    但是,您可以使用其他语言进行操作。如果您需要在多个平台上运行,我建议您研究 Java。与 c/c++ 类似的语言,您可以“编译”(某种)程序以在几乎任何计算机上运行。

    【讨论】:

    • 我看不出java和C/C++有什么相似之处
    • @Armen Tsirunyan:很简单:Java 基于 C++。
    • @Gorpik:语法上——也许吧,但两种语言的范式完全不同
    • @Armen:没那么多。语法当然是相似的,但 Java 和 C++ 都是面向对象的,而不是(比如说)像 Lisp 那样的函数式,所以当你知道另一个时很容易学习一个 - 这在这里很重要。
    • 我认为@Benubird 的建议有点被误解了。是不是更像是:“如果您需要在不同平台上运行您的软件,请使用 Java”......?我对此的补充是:如果您可以使用支持 vm-runtime 的语言(Java、.NET)。为多种模式编写和部署非平凡的 C++ 应用程序是一件痛苦的事......
    【解决方案5】:

    不要将处理器平台与操作系统平台混淆。 对于不同的操作系统平台,机器二进制文件完全不同。甚至不可能制作一对一的指令映射器。这是因为整个指令集架构可能不同,不同的指令组可能具有完全不同的指令格式,甚至可能缺少某些指令或目标平台。 只有模拟器或虚拟机才能做到这一点。

    【讨论】:

      【解决方案6】:

      实际上,一些操作系统支持这一点;它通常被称为“fat binary”。

      特别是,Mac OS 使用(使用)它在一个二进制文件中支持 PowerPC 和 x86。

      然而,在 MS Windows 上,这是不可能的,因为操作系统不支持它。

      【讨论】:

      • Windows 保持了大约 20 年的 ABI 兼容性。对胖二进制文件的需求并不多(即使它们只是针对一个平台的胖子)。此外,Windows 只能在 x86 和朋友系统上运行。
      • @Matt:嗯,根据维基百科,Windows NT 曾经在 PowerPC、DEC Alpha 和 MIPS R4000 上运行。现在有 x86 和 x86-64,胖二进制文件可能会有所帮助。
      【解决方案7】:

      Windows 可以毫无问题地在 64 位模式下运行 32 位可执行文件。因此,如果您在 32 位模式下编译,您的 exe 将是可移植的。否则,您必须发布 2 个版本的可执行文件。如果您使用 Java 或 C#(或任何字节码编译语言),JIT/解释器可以针对当前操作系统的模式优化您的代码,因此它是完全可移植的。但在 C++ 上,由于它生成本机代码,恐怕只能使用 2 个版本的二进制文件才能做到这一点。

      【讨论】:

        【解决方案8】:

        这样做的诀窍是创建一个包含机器指令的二进制文件,这些机器指令将在您想要支持的操作系统和处理器上的虚拟机中进行模拟。

        最广泛传播的此类虚拟机是 Java 虚拟机的变体。所以我的建议是看看compiles C code to Java byte code的编译器。

        此外,Windows 曾在其他 (Alpha) 架构上处理 x86 as a virtual machine

        【讨论】:

          【解决方案9】:

          总结其他答案,如果你想创建一个单个可执行文件,可以在多个平台上加载和运行,你基本上有两种选择:

          1. 创建一个“胖二进制”,其中包含多个平台的机器代码。大多数开发工具通常不支持此功能,并且可能需要目标平台上的特殊加载器;

          2. 编译为 JVM 或 .Net 的字节码。我听说过一种 C 编译器可以生成 Java 字节码(暂时记不起名字了),但从未使用过它,我也不知道实现的质量如何。

          通常,在 C 语言中支持多个平台的过程是为每个目标生成不同的可执行文件,方法是使用交叉编译器或在每个平台上运行编译器。这需要您考虑如何编写和组织源代码,以便在不影响整体程序逻辑的情况下轻松交换特定于平台的位,以实现不同程度的“轻松”。

          【讨论】:

            【解决方案10】:

            简短的回答是你不能,长的回答是有几个选择。

            1. 胖二进制。缺点是这需要操作系统支持。据我所知,唯一支持它的用户级操作系统是 OS X,用于将他们的 power pc 迁移到 Intel。
            2. 即时交叉翻译。由 Transmeta 和 Apple 使用。同样,我所知道的没有通用解决方案提供商。
            3. 一个 C\C++ 解释器。至少有一个我知道Ch。它在 Windows、Linux、OS X 上运行。注意 Ch 不完全兼容 C++。

            【讨论】:

              【解决方案11】:

              这个问题喜欢问“有没有办法可以从加拿大旅行到世界上的另一个城市?”

              答案是:“是的。”

              为了在没有任何虚拟机的情况下在 Windows 平台上将 C/C++ 源代码编译为可执行文件,您可以使用 Windows Legacy API 或 MFC(特别是在静态库中使用 MFC 而不是在 Dll 中使用 MFC)。这个可执行文件几乎可以在所有有 windows 的 PC 上运行,因为 windows 只能在 3 个平台上运行(x86、x64、IA64;除了支持 ARM 的 windows 8 和 8.1)。当然你应该将你的源代码编译为 x86 代码以在 32 上运行bit 和 x86-64 平台和 Itaniums 可以在仿真中运行您的 exe。但是对于所有运行 Windows 作为其操作系统的处理器(如手机中的 ARMS),您应该为 Windows Phone 或 Windows CE 编译它。

              【讨论】:

                【解决方案12】:

                可以写个中间库~如:

                      [ Library ]
                
                     [ mid-library]
                
                [linux part] [windows part]
                

                然后,您可以使用库,您的应用将是可移植的~~

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-12-19
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-09-19
                  • 1970-01-01
                  • 2013-10-07
                  相关资源
                  最近更新 更多