IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Linux  >

开发 LSB 认证的应用程序

实现二进制兼容的 Linux 应用程序的五个步骤

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

George Kraft IV (gk4@austin.ibm.com), 高级软件工程师,Linux 技术中心, IBM

2002 年 10 月 10 日

Linux 标准库(Linux Standard Base)向确保 Linux 应用程序之间的二进制兼容性迈出了一大步,它应该大大减少在多平台上操作所需的测试和验证。Linux 标准库的主席 George Kraft 用五个简单的步骤为您演示如何构建经 LSB 认证的应用程序。

简明新闻。Linux 向超越 UNIX 的源代码的兼容性迈出了演变的下一步。Linux 已实现 Linux 发行版或分发版之间全部的二进制兼容性,从而避免了它们之间的移植或重建源代码。应用程序开发者只需为每个 Linux 体系结构(例如 IA-32、PowerPC 或 Itanium)构建一次,然后部署。

Linux 有固有的二进制兼容性;然而,Linux 标准库(Linux Standard Base,LSB)已为应用程序设置了一些使二进制兼容性更为实用的规则和指导原则。(请参阅 参考资料,其中有 LSB 主页的链接。)为 Linux 而压缩-包装(shrink-wrap)LSB 应用程序要求您针对移植层来编码、使用正确的 ABI、用 LSB 应用程序检查器来测试、遵循 LSB 打包的指导原则和寻求 LSB 认证。本文给出了使用 LSB 资源来开发二进制兼容的应用程序的五个基本步骤。

第 1 步:针对移植层来编码

开放的系统(例如 UNIX 和 Linux)并不让应用程序直接访问操作系统的资源,它有移植层,应用程序针对移植层来编码。这是源代码兼容层,所有表现良好的应用程序都应该针对这层来编写。一般来说,这个编码层是一组 POSIX 应用程序编程接口(application programming interfaces,API)。(请参阅 参考资料,其中有关于单个 UNIX 规范(Single UNIX Specification)的开发的更多信息的链接。)然而,因为我们知道“GNU 不是 UNIX”,所以 LSB 为 Linux 重新定义了 POSIX,由此产生了 LSB 规范标准。

存在确保 UNIX 系统之间的应用程序的源代码兼容性的 UNIX 品牌的系统,也存在确保 Linux 应用程序的二进制兼容性的 LSB 品牌的系统;然而,应用程序必须使用兼容性定义的范围中的 API 或应用程序二进制接口(application binary interfaces,ABI)来编码。应用程序不能通过直接访问操作系统的资源来使用操作系统私有的接口或推翻移植层。

平台调优的应用程序

直接访问系统资源的应用程序或中间件被称为“平台调优的”。有时候这样做的目的是为了优化,但这将使软件在系统或发行版之间的二进制兼容的可能性大大降低。有时候,这种软件以平台为品牌,以用于操作系统的某个发行版,如果这是开发者的初衷,那没什么问题。然而,这种风格的编程超出了 LSB 的范围。

能够符合 LSB 规范的应用程序很可能在一组 LSB 品牌的系统之间实现二进制兼容。一般来说,如果应用程序把它们自己限于仅仅使用这 14 个系统库:libc、libdl、libm、libutil、libcrypt、libz、libpthread、libncurses、libX11、libXext、LibXt、libICE、libSM 和 libGL,那么它们有可能成为遵守 LSB 的应用程序。

如果应用程序不能把自己限于以上列出的库的接口,那么 — 为了最大限度地减少运行时错误 — 应用程序必须捆绑未被指定的库以使它成为应用程序的一部分,或者应用程序必须使该库静态地与应用程序链接。然而,这些库本身必须通过仅仅使用以上列出的库的接口来遵守 LSB。





回页首


第 2 步:使用正确的 ABI

对于二进制兼容性来说,把开发限于源代码 API 规范是不够的,这是因为不同的发行版和不同的系统有不同版本的库。为了实现二进制兼容,您必须针对 ABI 来开发。与 Solaris 类似,Linux 能够区分个别 ABI 的版本。所以,如果虚构的函数 kraft(x,y) 当前返回的是 double,但是 ABI 的更新版本返回的是 integer,那么您必须使用指定的版本来返回原先的聚集数据类型。为了做到这一点,LSB 已创建了存根库(stub library)。您可以链接到 LSB 存根库和 LSB 运行时链接器;然后您可以仅仅使用 LSB 指定的 ABI。或者应用程序的构建将因为使用了没有被 LSB 指定的东西而出现不能解析的符号的错误,或者 LSB 存根库将根据二进制规范来确保正确的 ABI。

为了简化应用程序与正确的 ABI 一起被编译,LSB 提供了 lsbcc 包装器脚本。 lsbcc 使用具有正确的 ABI 的 LSB 存根库、LSB 运行时链接器(ld-lsb.so.1)和对应 LSB 规范的头文件。所有您所需要做的就是从 LSB 下载 lsb-baselsb-cc软件包(请参阅 参考资料中的下载链接),然后把它们集成到正常的构建过程:

$ rpm -i ftp://ftp.freestandards.org/pub/lsb/lsbdev/lsbdev-base-1.2.2-1.i386.rpm
$ rpm -i ftp://ftp.freestandards.org/pub/lsb/lsbdev/lsbdev-cc-1.2.2-1.i386.rpm

$ lsbcc -o myapplication myapplication.c



$ CC=lsbcc make myapplication



$ CC=lsbcc ./configure; make myapplication

假设 kraft 是 libc 提供的 ABI 且它有不同的版本。如果 myapplication 使用 kraft ABI,那么我们可以比较应用程序与库映象以了解实际使用的 ABI。

$ /usr/bin/objdump -T myapplication | grep kraft
08048330 DF *UND* 00000032 GLIBC_2.0 kraft

$ /usr/bin/objdump -T /lib/i686/libc.so.6 | egrep kraft
000bb160 g DF .text 00000032 GLIBC_2.0 kraft
000bb160 w DF .text 00000032 GLIBC_2.1 kraft

myapplication 所用的 kraft 的正确的 ABI 应该是 GLIBC_2.0,所以它将返回 double。库和操作系统被允许演变,但是 LSB 刷新的频率较低从而为应用程序提供稳定的运行时环境。

术语

在书面的规范中陈述了 LSB“一致性”要求。“遵守”LSB 是开发者声称的一致性。LSB“认证”是通过认证程序来证明遵守 LSB(请参阅 参考资料中该程序的链接)。“LSB”是非盈利的 Free Standards Group,Inc. 的商标,Linux 标准库工作组就在这个非盈利机构运作。





回页首


第 3 步:用 LSB 应用程序检查器来测试

LSB 应用程序检查器 lsbappchk 是是否遵守 LSB ABI 的主要测试。以下是使用 getpid() API 的“Hello World”应用程序的示例。

   #include <stdio.h>
   #include <unistd.h>
   main()
   {
       printf("hello world: %d\n", getpid());
   }

一旦编译后,您可以检查 helloworld.c 以确定它是否遵守 LSB。lsbappchk 工具能比较应用程序所用的 ABI 符号与 LSB 书面规范所定义的 ABI 符号。

$ lsbcc -o hw_good helloworld.c

$ lsbappchk hw_good
lsbappchk for LSB Specification 1.2
Checking binary hw_good

我们从 lsbappchk 的输出可以看到它没有发现任何不遵守的异常情况;然而,如果我们对以上的示例稍作修改,使用私有的函数 _getpid() ,那么我们将看到不同的结果。

$ lsbcc -o hw_bad helloworld.c
/tmp/cc5CITzio.o: In function 'main':
/tmp/cc5CITzio.o(.text_0xd): undefined reference to '_getpid'
collect2: ld returned 1 exit status

我们从以上 lsbcc 的标准错误(stderr)输出可以看到 lsbcc 不能编译使用不符合规范的 ABI 的应用程序。使用 LSB lsbcc 工具有助于避免创建不符合守规范的应用程序。

但是,如果我们使用本机的编译器将会怎样?

$ cc -o hw_bad helloworld.c

本机的编译器允许应用程序与系统的私有接口 _getpid() 一起编译,但是我们知道根据 LSB 规范这样做是错误的。此外,我们知道我们应该从不使用任何以下划线为前缀的接口。

$ lsbappchk hw_bad
lsbappchk for LSB Specification 1.2
Checking binary hw_bad
Incorrect program interpreter: /lib/ld-linux.so.2
Symbol _getpid used, but not part of LSB

我们从以上 lsbappchk 的 stderr 输出可以看到应用程序与错误的运行时装入器关联并使用不遵守的 _getpid() ABI。所以,即使您不使用 lsbcc 来找出不一致的问题,您仍然可以稍后再使用 lsbappchk 来验证应用程序。这种方法并不是万无一失的,但是,它是很好的指示器。





回页首


第 4 步:遵循 LSB 打包的指导原则

一旦您使用 LSB 头来构建应用程序并与 LSB 存根库和运行时装入器链接后,您就可以开始以 LSB 的方式来打包应用程序。LSB 指定您应该使用 RPM v3 格式文件来打包应用程序。此外,您不可以使用触发器,也不可以依赖于预先安装或预先卸载脚本的执行顺序。您在那些脚本和应用程序中只能使用 LSB 指定的命令,因为无法保证其他命令是存在的或按预期的方式运行。LSB 没有指定安装这些打包成 RPM 的应用程序的工具。您可以在基于 RPM 的系统上使用 rpm 工具,在 Debian 上使用 alien。

为了避免在安装符合 LSB 的应用程序时名称空间冲突,属于基本操作系统或分发版的应用程序应被安装在 /sbin/、/bin/ 或 /usr/。系统管理员可以从源代码构建软件包并把它们安装到 /usr/local/ 目录。但是,第三方的附件软件包必须被安装到 /opt/ <package>/,其中 <package>是描述软件套件的名称。这些 /opt/ 应用程序的关联文件可以被放在 /var/opt/ <package>/、/etc/opt/ <package>/ 和 /opt/share/ <package>/。虽然 LSB 指定应用程序应被安装到 /opt/,但是最好在 RPM 规范文件中使它成为可重定位的前缀。这将在出现减少错误的情况下使安装程序重设位置并把文件放在其他地方。

当然,守护程序的启动脚本必须被放在 /etc/rc.d/ 中。应用程序的初始化脚本的名称必须是独一无二的且必须仅仅使用字符 [a-z0-9]。为了避免名称空间问题,它的名称必须在 Linux Assigned Names and Numbers Authority(LANANA;请参阅 参考资料)注册。如果脚本的名称被连字符连接,那么,或者最左边的字符串必须是在 LANANA 注册的名称,或者它可以是小写的全限定的域名。

除了在文件系统层次结构中避免名称空间冲突,符合 LSB 的软件包还应以“lsb-”为前缀。如果软件包的名称仅包含一个连字符,那么它的名称必须在 LANANA 注册。如果软件包的名称包含的连字符不止一个,那么第一组连字符之间的区域必须是在 LANANA 注册的 LSB 供应商名称或者是小写的全限定的域名。例如, lsb-java可能是 Sun Microsystems 在 LANANA 注册的名称,但是也可能有另一个未注册的 java 包名称 lsb-unregistered.org-java





回页首


第 5 步:寻求 LSB 认证

开发 LSB 应用程序的最后一步是使它获得认证。这个想法是任何 LSB 应用程序可在任何 LSB 分发版上运行。目前,至少有七个经认证的运行时环境(要想获得这个列表,请参阅 参考资料)。LSB 正在努力增加 LSB 应用程序的数量。

请注意,只存在“LSB 认证的”应用程序 — 那些已完成认证过程并签署了 LSB 商标许可证协议(LSB Trademark License Agreement)的应用程序。不存在类似“遵守 LSB 的”应用程序的东西,因为应用程序或者通过认证,或者没有通过认证。此外,LSB 认证的应用程序的所有者保证他们的应用程序在两个 LSB 运行时环境(分发版)和 LSB 样本实现上通过了所有者自己的功能验证测试(Functional Verification Test,FVT)。认证及其担保使 LSB 应用程序对消费者更有价值。

以下是作为应用程序开发者在 LSB 认证时应做的事情的核对表:

  • 使自己在 LSB 认证 Web 站点注册
  • 使用 LSB 提供的测试自行测试您的应用程序,然后把结果上载
  • 保证它通过您自己的 FVT
  • 完成一致性声明问卷(Conformance Statement Questionnaire)
  • 签署 LSB 商标许可证协议

然后,以上信息由认证机构(Certification Authority)来确认。最后:

  • 支付认证费用并签署 LSB 认证协议(LSB Certification Agreement)




回页首


结束语

LSB 的目标是使应用程序在任何 Linux 分发版上运行。LSB 实现这一点的方式是通过受一致性担保的支持的分发版和应用程序认证。如果您的系统或应用程序有不一致的地方,那么消费者可以要求您根据规范修正它。明确定义的 ABI 使“压缩包装”应用程序并把它放在货架上、在当地的计算机商店出售成为可能。产品盒子一侧的“系统需求”列表应该是“LSB v1.2”而不是 Linux 分发版的某个发行版本号。

为什么在您可以把市场扩大到任何遵守 LSB 的系统的时候把您的产品的可能的安装基数限于仅仅几个系统?LSB 的一个附带作用是在使软件在更多的 Linux 系统上安装的同时减少软件测试。

我奉劝您花一点时间,下载 LSB 开发环境,重建您的应用程序,然后使用 LSB 应用程序检查器来测试它以了解它的遵守程度。您可能发现您只需稍作修改就能遵守 LSB,您也可能需要重写使用私有的系统接口的部分。无论是哪种情况,您都能在了解情况后作出关于您的应用程序兼容的程度及原因的判断。



参考资料



关于作者

George 是 IBM Linux 技术中心的高级软件工程师,也是 Linux 标准库的主席。他从 1982 年开始在 UNIX 上开发,1993 年开始在 Linux 上开发。他在 1987 年获得 Purdue University 的计算机科学和数学的 BS 学位。您可以通过 gk4@austin.ibm.com与 George 联系。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款