nevercgoodbye 2011-11-09
Linux可移植性,如何才能实现软件预期的灵活性.不同硬件和软件平台用户都可以不做任何修改或者只做极少的修改就可以使用软件.
常见的可移植性需求有:
a.平台之间的可移植,例如unix和linux以及mac
b.linux不同发行版之间
使用可移植函数库并充分使用各种自动配置工具编写的linux可以满足以上要求.
1.抽象层
在linux内核之上穿件标准化函数库,例如glibc.内核只负责处理繁琐的硬件细节.系统工具可以绕开函数库直接使用内核的接口.
2.linux标准化
a.LSB (linux标准化规范 Linux Standards Base)
主要基于POSIX以及单一UNIX规范.
它的目标是:在符合LSB特定版本要求的指定主机架构上,在不同的发行版和同一发行版的不同版本之间提供正真的二进制兼容.
LSB是一个二进制ABI标准.它使用rpm包作为可移植软件包格式概念基础,并对LSB兼容包的命名和内部内容就行了约束.
3.linux软件包开发注意事项
当编写自己的应用程序时,需要在设计中考虑将依赖于哪些外部软件和函数库,哪些软件将由自己交付,如何支持不满足应用程序要求的发行版.
4.可移植的源代码
以上都是linux可移植的泛泛之谈.代码可移植才最重要.
在linux编写的软件不仅仅要运行在相同平台发行版之间可以二进制兼容,还应该在大多数提供正确函数库和必备条件的系统中成功编译.编译过程必须小心的确定不同软件环境之间的差异.
为了辅助不同编译环境之间的源代码级的可移植性,人们创建了gnu的自动化工具autotools.autoconf,autoheader,libtool,automake等许多脚本和工具一起工作构成gnu编译系统.这个工具自动运行一系列的测试以获得对用户所处硬件和软件环境的理解,然后再确定是否可能在这一特定的软件环境中编译软件.当准备号合适的源代码集之后,就可以使用你可能早已熟悉的configure,make,make install,来编译软件了.
a.gnu自动化工具
我们这里组织一个案例hello.c,库libhello,以及configure判定大端小端
hello.c:
#include "hello.h"
int main()
{
print_message("hello world!\n");
#ifdef WORDS_BIGENDIAN
printf("this is a big endian\n");
#endif
return 0;
}
help.c:
include <stdio.h>
void print_message(char *msg)
{
printf("the message is %s \n",msg);
}
hello.h:
void print_message(char *msg)
执行以下命令:
gcc -shared -fPIC -o libhello.so help.c
gcc -lhello -L. hello.c
export LD_LIBRARY_PATH=`pwd`
./hello
1)gnu autoconf
configure用于建立包含一个特定系统动态信息的头文件,这些动态信息用于源代码测试.例如,一个编译周期通常会创建一个头文件config.h.它包含很多#define声明对应已经经过测试的特性.如果gnu configyre确定本地的环境适合编译软件,那么这些定义将有助于增加软件的灵活性.因为他们允许必要的时候进行条件代码编译.
以下为一个configure.in的例子:
##这一句是autoconf需要的最低版本
AC_PREREQ([2.68])
##设置软件包的名字,版本号,以及作者邮箱
AC_INIT([hello], [1.0], [[email protected]])
##以下是设置包含进configure中的特征和测试需要.
#设置主机编译还是为另一个目标系统编译
AC_CANONICAL_SYSTEM
#测试目录下是否存在hello.c,用于确保用户在正确的目录下.
AC_CONFIG_SRCDIR([hello.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.测试是否存在c编译器
AC_PROG_CC
#测试标准头文件的可用性
AC_HEADER_STDC
#测试大端小端
AC_C_BIGENDIAN
#测试其他的头文件
AC_CHECK_HEADERS
#指定gnu autoconf运行之后输出的文件
AC_OUTPUT(makefile)
最后执行autoconf
configure脚本将从configure.in文件中自动生成基于可移植的shell代码.