68 个回答
这其实是个伪命题。
操作系统给应用软件提供的API,本来就是统一运行环境。操作系统一直都在努力给软件提供一个统一的运行环境。他们确实是这样想的。
如果为x86Windows写的代码全都能在armWindows上面运行,微软开心不开心啊?当然开心,睡觉都要笑醒。——所以操作系统产商当然有动力提供统一运行环境。
但是呢?实际上应用软件的开发者有千千万万,需求有形形色色,人的行为总会有多样性。所以实际上他们做出的事情就不可预期。
举个例子:Android 系统。一开始就设计为使用java虚拟机,这,总该是非常统一的运行环境了吧?
然而实际上呢?由于有相当多的现有代码使用C或者C++开发,要复用这些代码必须使用NDK。另外就是,java虚拟机并没有提供足够完备的功能,比如串口通讯就必须依赖C写的库。jvm无法完成。
各种原因敦促了 android 必须开放NDK编译,然而NDK意味着,不同的CPU架构必定会生成不同的代码(除非是实时编译)。
为了解决这个问题,最常见的办法是: 将所有可支持架构的编译结果都打包到程序中,程序运行的时候判断当前CPU架构决定加载哪一份代码 。
比如,苹果当年切换到intel处理器的时候,就是这么做,要求开发者打包应用的时候将新旧两个体系的应用都打包进去。
Google有没有这么要求?有:Google 要求 NDK 开发者对 arm,arm64,mips,x86 等架构全都进行打包,而安卓的安装器在安装app到目标设备的时候,会根据目标设备的实际架构,只选择目标架构安装上去。
我们看到,Google的想法是好的,实际上呢?实际上,开发者们根本就不愿意打包所有架构,往往都偷懒只打包 armeabi 架构。
然而现实是:7年来生产的所有新款手机都是 arm64 架构的。而Android Studio从3.4开始就默认只打包手机对应架构的ndk包(对于手机来说,这意味着AS默认只打包arm64架构,除非你在gradle设定中强制设定ndkfilter)。
可是相当多的开发者依然,宁可在gradle中强制设定ndkfilter,也不愿意提供arm64版本的包。——当然,他们同样也没有提供 x86,没有提供 mips 的包。
那么问题来了,操作系统能不能只接受源代码,然后,到不同平台架构上实时编译,这样确实就什么架构都能跑了?
答案是:操作系统确实能够这么做,但软件开发商不愿意啊。
如果你的代码支持让操作系统实时的到目标机去编译,那么你这个代码就相当于完全没有加密的,很容易被破译,从公司管理的角度,这样暴露自己的IP(智力财产)是不合规的。
我的看法:理论上可以这么做,只要规定软件发布必须把主流CPU架构都打包就好。但实际上只有苹果能做到这一点。苹果可以规定你不按照我的要求打包就不让你发布。安卓跟Windows就不行。
这大概就是自由的代价吧。允许软件开发有更多自由,就必然没法阻止开发者使用或者只提供某个特定架构才能用的库。操作系统如果无法从软件发布的源头上管控软件发布,那么就没有办法支持所有的情况。