您刚刚将功能丰富的更新下载到您喜欢的开源应用中。一切正常,您可以在其他设备上使用它-因此也该将它们推广到其他设备上。
除了闪亮的新Linux笔记本电脑与Windows安装包不兼容之外。您的Android平板电脑怎么样?苹果手机? PS4?您为什么不随便拿该软件并随便使用它?让我们探讨实现“一次购买,在任何地方运行"这一梦想的一些不同障碍。
软件开发和OS架构
了解为什么软件无法跨操作系统运行需要一点点(
在台式机,服务器和移动设备(即非Web)的非常基本的软件开发流程中,程序员将:
它是一个组合这里涉及我们的第一步和第二步。 编译软件或将其从代码转换为计算机可以理解的零(机器语言)的过程非常复杂。我们不会详细介绍它,但是从高层次上了解会发生什么是很有用的。
OS体系结构
要理解的一个重要点是操作系统不是单个实体。而是由软件层组成。
操作系统的内核负责与计算机的硬件进行通信。软件将其命令传达给内核,内核再向硬件发出命令,以(例如)从硬盘读取文件或在屏幕上绘制窗口。它基本上可以协调硬件和各种软件之间的所有信息(无论是存储的数据,计算结果还是用户输入的信息)。内核通过系统调用使所有这些功能对软件可用。
每个操作系统的内核都会以不同的方式实现系统调用,就哪些可用,它们是什么而言打电话,或者他们采取什么选择。结果,软件需要考虑到它所针对的每个OS内核所支持的系统调用。在Linux中,用于将数据发送到GPU的系统调用可能具有不同的名称,需要提供的信息列表,或者在Windows中都具有这两种名称。确切的调用甚至根本不存在。
在许多情况下,软件并不直接调用内核。而是调用系统库或基本功能的集合。存在图书馆,因此(例如)将文件保存到硬盘的每个程序都不需要编写函数即可。相反,它只是链接到系统库并使用现有功能。适用于Linux的GLibC库就是一个很好的例子,Win32 API中的.DLL文件或Mac的/ System / Library目录的内容也是如此。
系统库充当应用程序之间的一种转换程序和用于日常任务的内核。应用程序对这些库进行函数调用,这些库处理许多底层细节。为了方便起见,它们还可以对内核进行系统调用。您可能已经猜到了,这意味着这些库是为特定内核编写的,因此不能在具有不同内核的操作系统中使用。
操作系统执行头
通用软件的最后障碍是操作系统可执行文件的格式。操作系统期望其运行的文件遵循特定的二进制文件格式。例如,在Linux和FreeBSD等操作系统上运行的可执行和可链接格式(ELF)文件必须以某些字节指定文件的某些属性,如下图所示。
能够显示的strong>应用程序二进制接口(ABI)尤其重要。 ABI结合了处理器,内核和系统库的可用调用,它与应用程序编程接口(API)类似,因为它定义了两个程序之间如何通信。但是API是程序员(人类)在源代码中使用的一种东西,用于指示两个软件应该相互交谈。一旦编译并运行了软件,ABI便真正允许他们这样做。每个操作系统都实现一个特定的ABI,该ABI在同一操作系统的版本之间可能会或可能不会更改。
通常,操作系统会实现自己的ABI,具体取决于处理器类型,内核的组合,以及任何标准系统库。但是有时候一个操作系统会实现多个。例如,FreeBSD支持Linux二进制文件,因为它提供了Linux ABI作为FreeBSD内核(而不是Linux内核)的附件。
例外:解释性软件
基于上述内容,我们了解到开发人员只为一种目标类型编写软件。系统。除非他们不这样做。您可以下载许多应用程序,然后在Mac上运行它们,然后在Windows上复制并运行它们,甚至可以再次复制并在Linux上运行而没有任何问题。怎么可能呢?
直到现在我还躺在床上吗?
事实证明,有一类软件看起来像是表面上“随处可见"。可以在任何受支持的平台上下载并运行它-关键字“受支持"。实际上,您正在下载该应用程序的源代码,而另一个应用程序(解释器)正在运行源代码直接实时。这有点过分简单了,所以让我们看一下它在几种语言中的确切工作方式。
当Java首次发布时,它的承诺是(字面上)“编写一次,就可以在任何地方运行"。使用Java函数创建应用程序,以用于保存文件,进行计算或创建应用程序窗口。然后,每个受支持的计算机平台的 Java运行时环境(JRE)将运行代码,并将其转换为本机OS功能。那么,Java的窍门是它不会在操作系统上“直接"运行。它运行在JRE的一部分中,该部分称为 Java虚拟机,并且可以在操作系统上运行。
通过在应用程序和操作系统之间插入此附加软件层,Java使您可以专注于一套跨操作系统相同的功能。您告诉Java您想做什么,然后让系统的JVM担心如何实际执行。下图显示了这一操作,JIDE Software的Java Desktop Application Framework在Mac(上),Windows(左中),“ pure Java"(右中)和Linux(下)中显示了相同的应用。
Java程序无法实时精确地“自行"编译。而是,Java编译器会将它们呈现为“字节码"。您可以将字节码视为一个半熟的程序。开发人员发布应用程序时,会尽可能地对其进行编译,而无需知道它将在哪个操作系统上运行。当您实际启动它时,JVM会“其余部分"来适应主机OS的特定功能。
一种流行的解释语言是Python。当您运行Python脚本时,Python解释器会将代码翻译为操作系统的指令。它的功能也类似于Java:当您从应用程序外部“导入"代码时,它将在首次运行时被编译为字节码。然后,解释器将知道在随后的运行中原始代码是否已更改,这时它将重新编译为新的字节码。
这种“按需"运行的很酷的副产品是您可以使用解释器以交互方式开发脚本。只需在命令行中键入“ python",即可启动解释器,然后您可以运行代码并立即查看结果。
这意味着开发人员可以试玩并调整“实时"的内容。然后,一旦一行代码完成了他们想要的操作,就将其复制并粘贴到脚本文件中(这比未经解释的语言程序员所要做的“代码-编译-测试"循环要高效得多)。
即使软件相同,也可能不是
对于用户来说,不幸的是,技术行业尚未开发出真正的“通用"格式。而且它可能永远不会这样做。引入这些类型的标准通常会导致“最小公分母"解决方案,并且为了让所有人都认可而做出让步。
您如何看待?您是否宁愿拥有通用兼容的软件,即使它并不那么好?还是您对所使用的操作系统感到满意,并且对其他平台的应用程序不感兴趣?在评论中让我们在下面知道!
图片来源:Masterchief_Productions / Shutterstock