Linux和Windows之间的移植工作如何?

如果一个特定的软件被运行在一个平台上,并且程序员/公司/任何想把它移植到另一个平台上,那究竟做了什么? 我的意思是,他们只是重写Linux或Windows特定的引用到另一个相当于? 或者是一个完整的重写需要?

试图了解是什么让它成本太高,以至于很多主要的厂商不把他们的软件移植到Linux上(特别是在考虑Adobe)

谢谢

Solutions Collecting From Web of "Linux和Windows之间的移植工作如何?"

这是跨平台工具包(如qt或gtk)的要点,它们提供了一个平台不可知的API,它委托给编译该程序的任何平台。

一些公司不使用这样的工具包,并且自己编写(无论出于何种原因 – 很可能与优化有关),这意味着他们不能仅仅为其他操作系统重新编译它们的代码。

也有可用的库,至少在一个特定的区域,缓解了Windows API调用Linux的端口。 请参阅Windows到Linux移植库 。

移植一个未经平台独立的软件可能是一项艰巨的任务。 通常,代码与非可移植的API(无论是第三方还是OS操作系统库)根深蒂固。 如果第三方供应商没有为您正在移植的平台提供API,那么您几乎被迫完全重写该功能,或者找到另一个可移植的第三方。 这只能是非常昂贵的。

最后,移植软件也意味着支持另一个平台,这意味着聘请一些专家,并培训支持来回答更复杂的查询。

最后,这样一个过程可能会非常昂贵,只需很少的额外销售。 可悲的是,这个决定很简单:专注于当前平台上的新功能,您知道您的客户将付费。

根据我的经验,有三个主要原因是为什么在一个平台上采用大型现有程序并将其移植到另一个平台上是成本高昂的:

  1. 它有(不一定故意)广泛地使用一些图书馆或API(通常是GUI,但也有很多其他的东西),原来不存在于另一个平台上

  2. 它已经在不知不觉中变得依赖于编译器或其他工具的非标准特性或古怪

  3. 它是由不知道你必须使用一些古怪的功能来让其他平台上的东西能够工作的人写的(比如一个没有使用正确的__declspec指令的Linux库) 。

如果从一开始就考虑设计目标,那么编写跨平台的应用程序要容易得多,我有三个具体的建议:

  • 使用通常从特定于平台的API和库中获得的便捷事物的Boost-oodles,但是通过使用Boost,您可以获得跨平台的功能。

  • 使用跨平台库进行所有的GUI编程。 这些天我最喜欢的是Qt,但也有其他值得的。

  • 在两个平台上每天构建和测试,从不为代码提供机会,只在一个平台上发展依赖关系,发现它只是为时已晚。

如果软件是为单个操作系统编写的,那么可能会有大的返工。 第一步是将所有平台特定的代码绝对移入代码库的单个区域; 这个区域应该只有很少的应用程序特定的东西。 然后重写这个新的目标操作系统的代码的孤立的部分。

当然,这掩盖了一些非常重要的影响。 例如,如果你的第一个版本的目标是Win32 API,那么任何GUI代码都将与Windows密切相关,并且为了保持你的理智,你需要将所有的代码移动到一个跨平台的GUI框架,比如Qt或GTK。

在Mono下,你可以编写一个在两个平台上工作的C#Winforms程序。 但是为了做到这一点,Mono团队必须编写自己的Winforms库,它基本上复制了Winforms的所有功能。 所以还没有免费的午餐。

大多数软件在某种程度上是便携式的 在C应用程序的情况下,除了路径变化等,该区域还会有很多#ifdefs。

很少有Windows / Linux版本的相同软件不共享一个通用的代码库 – 这实际上意味着它们只能共享一个通用名称。 维护更多的代码库总是比较困难,但我认为移植应用程序的实际问题与技术方面无关,而与业务方面有很大关系。 Linux的用户比Windows / OSX要少得多,他们中的大多数人都希望所有东西都像啤酒一样自由,或者只是出于某种宗教原因而讨厌商业软件。

当你开始思考这个问题的时候 – 大多数开源软件都是多平台的,不管用什么语言来实现它。 这说明了自己…

PS免责声明 – 我是自由和开源软件的狂热支持者,我不想侮辱任何人 – 我只是分享我对这个话题的看法。

有很多原因将应用程序移植到不同的平台可能非常困难,通常是因为应用程序用来与系统进行通信的一些接口不可用,需要自己实现这些接口应用程序所依赖的库,或重写应用程序,以便使用替代函数。 今天的大多数语言在硬件架构和操作系统上都是非常便携的,但问题在于库,系统调用以及OS(或平台)提供的其他接口。 更具体:

  • 编译器的配置和它们提供的标准功能可能有所不同。 在Windows上,C / C ++最流行的编译器是Visual Studio,而在unix上是gcc和llvm(结合标准库glibc或BSD libc)。 他们期望不同的标志,不同形式的声明,产生可执行文件和共享库的不同文件格式。 尽管C和C ++具有标准库,但它们在不同平台上的实现方式不同。 有一些系统的目标是编译便携,如Autotools,CMake和SCons。

  • 在标准库之上还有OS提供的附加功能。 在Windows上,它们被win32 API覆盖,在unix系统上,这些是POSIX标准的一部分,具有各种GNU,BSD和Linux特定扩展,还有简单的系统调用(应用程序和操作系统之间的最低级别接口) 。 在Windows上通过cygwin和mingw等系统可以使用POSIX函数,通过Wine可以在unix上使用win32 API函数。 问题在于这些实现并不完整,往往有一些小的(但重要的)差异。

  • 与桌面系统的通信(为了制作GUI界面)的做法是不同的。 在Linux上,这可能是X Window系统(连同Freedesktop库)或Wayland,而Windows有自己的系统。 有GUI图书馆试图提供这些抽象接口,如Qt,GTK,wxWidgets,EFL。

  • 操作系统提供的其他服务,例如网络通信可能以不同方式实现。 在Windows上,许多应用程序使用.NET库,因此在Unix系统上只有有限的支持。 一些unix应用程序依赖于Linux特有的功能,如systemd,/ proc,KMS,cgroups,命名空间。 这限制了在Unix系统(Linux,BSD系统,Mac OS X等)之间的可移植性。 即使.NET库在不同版本之间也不是很兼容,而且它们可能不适用于较早版本的Windows或嵌入式系统。 Android和iOS完全不同。

  • Web应用程序通常是最便携的,但HTML5是一个实时标准,许多接口在某些浏览器/ Web引擎中可能还不可用。 这需要使用polyfill,但通常比“原生”应用程序的痛苦少得多。

由于所有这些限制,移植可能是相当困难的工作,有时候从头开始创建新的应用程序更容易,要么专门用于其他平台,要么使用跨平台抽象库/平台(如Qt或Java),或作为一个Web应用程序(可能捆绑在像Electron这样的东西)。 从一开始就使用它们是一个好主意,但许多程序员选择不这样做,因为应用程序往往看起来和行为与平台上的“本地”应用程序有所不同,而且它们在交互方式上可能也会更慢,更受限制与操作系统。