最近工作中遇到个问题,就是多个系统跑着不同版本的内核,不同架构的ARM芯片,上层的业务程序能否二进制归一(共镜像)。
根据自己对Linux的了解,glibc是否可以在ABI层面做到向前兼容。那个整个系统能否做到呢?这勾起了我的分析和思考。
试想一下,一个程序从源代码到最终的二进制,有哪些组件参与了编译和链接过程,大概如下:
需要分析各组通能否做到二进制兼容性,以及是如何做到的。下面我对各组件,以思维导图来分析是否能满足ABI兼容性。
上面的思维导图把我想到的组件都进行细分,把每个细节都覆盖到。当然,还会有一些细节是我没有想到的。下面对不那么常见的组件进行说明:
从分析来看,大部分软件都是可以保持向前兼容的。这就是为什么从一台机制上的程序拷贝到另一台机制上,程序还能正常运行。
噢,这到底是巧合呢?还是什么:所有Linux 程序都是在所有机器上运行。我也带个着这个问题去找一些资料。
想信大家听说到POSIX规范,Linux Standard Base(LSB)规范。起初,我以为LSB是API规范而非ABI规范。当我去深入分析时,发现它是一个ABI规范,它解决两方面的问题:
最近Linux基金会发起LSB项目就是希望Linux发行商能做到相互兼容,并且也能向前兼容。解决Linux应用的可移植性和兼容性。
LSB实际是是一组ABI接口的定义,它规范了运行环境所需要的类型,宏,变量和函数的二进制接口。
那么,哪些东西受到LSB的制约呢?也即LSB规范约束的范围多广。刚开始,我还以为只有kernel, glibc等一些关键的组件。事实上,打开LSB官网说明会发现它包罗万象,从命令,ELF,glibc接口,到桌面,脚本语言等等都有相关的规定。
毫无疑问,kernel, glibc等都应该遵守LSB标准。事情上,并非如此。 LSB希望Linux发布版(如Redhat, Suse, Ubuntu)能遵守LSB,因此它提供了LSB的测试套和LSB的认证服务。
那么Kernel和glibc就真的不需要考虑LSB了吧,答案是否定的。整个kernel/glibc和各大Linux知名组件都以开源方式进行开发,它里面的技术早已不是什么密秘了,各大公司都有工程师参与,所有公司都希望这些软件都是遵守LSB,使所有软件都能轻易地融合在一起,不希望让发生行商花很大力气去集成。因此所有软件都是会尽量遵守LSB规范,但无法排除有那么一两个例外的Case。
glibc是大家用得最多的组件,也算是我比较了解的组件之一,到网上找了一些它的兼容性分析,发现它也不能保证100%向前兼容。不能完全兼容的发生在2.16.0和2.13两个版本上。当前对于一般的软件,这个兼容性是完全足够了的。
那么Linux能做到向后兼容性吗?答案是否定的,因为LSB也无法做到向后兼容。
那问题来了,如果我需要做到向后兼容呢?假如有下面这种场景:
很多服务器都是Ubuntu 7.04,算是8年前的服务器了,数量很多。同时也会有服务器使用了12.04,数量较少。但12.04上的编译器较新,支持很多安全功能。架构师的诉求就是:能否基于12.04版本运行环境做开发编译,生成的服务程序能同时运行在7.04和12.04两个服务器上。
我能想到的解决办法:
- 找到Ubuntu 7.04和12.04两服务器运行软件,所遵守的LSB版本,服务程序只能调用这两LSB完全兼容的接口
- 在编程和链接服务程序时,可以指定程序使用的LSB标准(Ubuntu 7.04版本的LSB)。
对于第一个方法,个人认为可行,但约束很多。方法二未知可行,后续再分析
这就是“向后”兼容性想讨论的一个问题。它不是真正的向后兼容性,完全是依赖于向前兼容来实现的。
兼容性,完全不是我熟悉的东西,只是工作上遇到问题,做了初步分析。希望通过blog记录我的思考,当某一天,我对这个知识有深入的经验,再跟大家分享。如有写得不正确,或者误导的内容,请指正,谢谢!
2015/7/11 于上海 灿鸿台风来袭
版权声明:本文为博主原创文章,承蒙转载请注明作者和出处
原文地址:http://blog.csdn.net/linyt/article/details/46841845