为什么编译器通常只为安装它们的平台生成可执行文件?


10

我是C ++开发人员,为了更好地理解跨平台开发,我试图更好地了解编译器的一些实现细节以及它们如何精确创建OS特定的二进制文件。在研究过程中,我意识到,至少有一段时间,您为特定平台下载的大多数编译器仅针对该平台编译了二进制文件。因此,如果您下载了Windows编译器exe附带的IDE,则该编译器将只能针对x86-x64 Windows应用程序而非Linux或Mac应用程序编译程序。

现在,我了解到不同的平台需要不同的二进制格式,但是为什么说Windows上的可视C ++编译器很难生成Linux二进制可执行文件呢?只要您具有运行CPU的汇编指令以及特定于OS的库,您是否不应该能够在任何计算机上为任何平台编译可执行文件?


5
交叉编译器很多:我不确定为什么您认为交叉编译不常见。鉴于Microsoft需要Windows锁定,因此Visual C ++很有用,但它们甚至在VS2017中提供了Android编译器工具。

似乎还有很多其他站点似乎证明交叉编译器很难实现,直到最近才出现了更多的跨平台编译器。如果这是真的,那么我只是想知道如果您只需要某些CPU汇编指令并且本机系统需要相应的OS,那么交叉编译就会变得很困难
Jason

我认为您在这里有一个术语理解问题,可能会造成混淆。您可以交替使用趋势“交叉编译器”和“跨平台编译器”,但是它们是不同的(尽管相关):交叉编译器是针对与您使用的平台不同的平台的编译器,跨平台编译器是一种编译器,它使用一个中间步骤将源语言的处理和优化与特定于平台的代码生成分开,以便可以使用它。 ..
Jules

...用于以最小的更改为多个目标平台编译代码。这些事情是最新的创新,更加复杂。
Jules

Answers:


18

是什么使得很难说Windows上的可视C ++编译器生成linux二进制可执行文件?

除了不愿意微软这样做,绝对没有。障碍不是技术性的。

开发工具链只是接受输入并产生输出的程序。Visual C ++生成x86程序集,然后使用汇编程序将其转换为COFF目标文件。如果微软想让它生成ELF,那只是代码:汇编进入,ELF退出。目标文件或库没有什么神奇的;它们只是一种易于理解的格式的数据。

回到石器时代,交叉编译要困难得多,因为通常情况下,您会在目标平台的运行平台上组装工具链。这意味着,如果世界上只有VAX,M68K和Alpha架构,那么一整套交叉编译器将需要编写其中的九个,大多数都是从头开始的。(VAX到VAX,VAX到M68K,VAX到Alpha,M68K到VAX,M68K到M68K等),这有点夸张,因为可以重复使用VAX编译器的某些部分,附加到每个目标的代码生成器(例如,分别为VAX编写的VAX,M68K和Alpha)。

当我们开始使用与特定处理器(例如C)无关的语言来编写编译器时,这个问题就消失了。走这条路线意味着您需要用C编写整个工具链一次,并使用针对本地平台的书面形式用C编译器来构建它。(在本地平台的编译器上自举后,通常会使用编译器进行重新编译,但这是另一个讨论。)这样做的结果是,构建交叉编译器的工作基本上与在其上构建本机编译器相同。本地平台。唯一的显着区别是,在构建过程中的某个地方,您告诉它在目标平台的代码生成器中进行编译,而不是在本地平台的代码生成器中进行编译,这将是合理的选择。

随着编译器体系结构的发展,在产品中轻松包含并构建所有代码生成器并选择在运行时使用哪个代码生成器变得很方便。Clang / LLVM可以做到这一点,我敢肯定还有其他人。

一旦有了有效的工具链(编译器,汇编器,链接器),就可以从源代码构建库,最终您将获得为其他平台生成可执行文件所需的一切。


现在,这是最好,最深入的答案。我认为历史确实有助于理解背景​​。
杰森

3
@Jason有时候老是值得的。:-)
Blrfl

4
“除了不愿意微软这样做,绝对没有。” –我不会称其为“不愿意”。微软是一家公开交易的以利润为导向的公司;他们对股东和利益相关者负有一定责任。他们需要雇用,培训和支付 Linux后端的开发人员,他们需要雇用,培训和支付 Linux后端的测试人员,他们需要雇用,培训和支付熟悉Linux后端的支持人员,他们需要设计,开发,维护,支持和扩展的代码,所有的平台,...
约尔格W¯¯米塔格

……超出其核心业务。而所有这些只是在您可以很好地使用的现有n个编译器中添加第n + 1个编译器。微软与GCC,Clang,ICC(Intel),xlc(IBM),Digital Mars,tcc,pcc,TenDRA,Metrowerks,PathScale等竞争的商业利益是什么?就我个人而言,我认为没有。
约尔格W¯¯米塔格

3
@JörgWMittag- What would be the business benefit ... I don't think there is any.这似乎是不愿意这样做的充分理由。
Blrfl

8

是的,如果您拥有有关目标平台的所有信息,那么您实际上在哪个平台上运行都没有关系。

容易出现两个问题:

  1. 人们不会关注它,因为这是一种不太常见的情况。通常,您交叉编译的唯一东西就是编译器,因此您可以停止交叉编译。更少的关注意味着更差的支持。
  2. 不平凡的程序不仅仅需要代码。当您拥有正在运行的平台的库时,处理库包含/链接将变得容易一些。它们将以众所周知的编码位于一个众所周知的位置。

当然,这些并不是不可克服的。通常,您会得到针对其运行平台的编译器,因为这是人们想要的。


我知道了。谢谢你的澄清。现在对我来说绝对更有意义。
杰森

我将其归咎于智能感知。
JeffO

2

我不同意你的前提。有数百万的Android和iOS开发人员。他们使用在Windows或Mac上运行的编译器,从而为完全不同的计算机生成代码。

如果没有市场需求,您将不会得到交叉编译器。例如,为Linux桌面开发代码的人大多拥有Linux桌面,并且将使用基于Linux的编译器-如果您可以直接在编译该应用的计算机上直接运行应用程序而无需通过网络进行传输,则速度会大大提高。使调试器在同一台计算机上运行,​​依此类推。

那么,如果他们的编译器也能为Linux构建,微软将赚多少钱呢?大约$ 0。将为Windows创建更多的软件?没有。将创建多少个Linux软件?不知道,但这不是Microsoft关心的事情。费用是多少?相当可观。编译器必须没有错误。他们必须经过测试。

另一个问题:如果您在Windows上编写编译器,则需要知道如何编写Windows软件的人员。如果您为Linux编写编译器,则需要知道如何编写Linux软件的人员。如果您为在Windows上运行的Linux编写编译器,突然间,您将需要同时了解Windows和Linux的开发人员的稀有产品。


“有数百万的Android和iOS开发人员。他们都使用Windows或Mac上运行的编译器,从而为完全不同的计算机生成代码。” 嗯,不是,他们不是。许多很多Android开发人员都使用Linux,实际上,根据StackExchange自己的调查,它是最受开发人员欢迎的平台。
Miles Rout
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.