ivaneeo's blog

自由的力量,自由的生活。

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

#

怎样才能使程序具有可移植性呢?
.尽可能避免针对特定系统的假定和方法.例如,不认定程序只在OpenLinux系统上运行,或者只在使用RPM包管理系统的系统上使用.
.隔离依赖于系统的部分.如果说有了一种特殊的GUI环境,例如ncurses,那么要把GUI部分的代码单独放在它自己的模块中.这样做可以使移植任务变得简单,
比如让程序使用基于X的GUI环境或者另一种基于文本的GUI S-Lang而不是ncurses.
.尽可能复用已有的接口.为什么一定要重新创造已经存在的东西呢?从常用的数据库管理库,比如Berkeley DB或GNU DBM中选出一种代替你自己的数据库管理库.
.使用标准接口,比如多种POSIX标准;标准语言,比如C和C++;以及标准库,比如标准C库,NAG数学库和terminfo等常用库.

http://www.cs.wvu.edu/~jdm/research/portability/portbib.html 上提供的参考书目是个很好的资源.
posted @ 2005-08-04 21:35 ivaneeo 阅读(167) | 评论 (0)编辑 收藏

最好的一点是,autoconf生产的脚本是自包含的,因此在目标系统上编译软件时不需要在其系统上安装autoconf,使用者所需要做的只是在软件发布版本的源程序目录中键入./configure.

为了生产configure脚本,需要在源文件树的根目录下创建名为configure.in的文件.configure.in调用一系列autoconf宏来测试程序需要的或用到的特性是否存在,以及这些特性的功能.
posted @ 2005-08-04 21:28 ivaneeo 阅读(225) | 评论 (0)编辑 收藏

每个configure.in文件必须在开始所有测试前调用AC_INIT,并且在结束所有测试后调用AC_OUTPUT.而事实上,也只有这两个宏是必须的.AC_INIT的语法如下:
  AC_INIT(unique_file_in_source_dir)
  unique_file_in_source_dir是在源代码目录下的一个文件,对AC_INIT的调用在所产生的配置脚本文 件中生产一条shell命令,通过检查unique_file_in_source_dir是否存在来验证当前目录是否正确.
  AC_OUTPUT创建名为makefile或其他名字(可选)的输出文件,其语法如下:
    AC_OUPUT([file...[,extra_cmds[,init_cmds]]])
  其中file是用空格分隔的输出文件列表,通过复制file.in到file来生成这些文件.extra_cmds是一个命令列 表,附加在config.status之后,在重新生成配置脚本时会用到它,init_cmds也将插入到config.status中,但其位置正好在 extra_cmds之前.
posted @ 2005-08-04 21:27 ivaneeo 阅读(423) | 评论 (0)编辑 收藏

下面的调用次序只是建议性质的,而非必须:
AC_INIT
  测试程序
  测试函数库
  测试头文件
  测试类型定义
  测试结构
  测试编译器行为
  测试库函数
  测试系统调用
AC_OUTPUT

在这里有必要注意一下configure.in的写法.每一个宏调用应该占据单独的一行,这是因为多数autoconf宏都需要一个新行来结束命令.
  一个多参数的单宏调用可以超过这个每宏一行的规则.这时应该使用\来续行并且用m4所能识别的括号[]来括起所有参数.下面的两个宏调用是等价的:
  AC_CHECK_HEADERS([unistd.h termios.h termio.h sgtty.h alloca.h \
  sys/iteimer.h)
  AC_CHECK_HEADERS(unistd.h termios.h termio.h sgtty.h alloca.h sys/timer.h)

最后,可以使用,m4的注释符号dnl在cofigure.in中插入注释.例如:
  dnl
  dnl This is an utterly gratuitous comment
  dnl
  AC_INIT(some_darn_fie)
posted @ 2005-08-04 21:27 ivaneeo 阅读(174) | 评论 (0)编辑 收藏

在开始测试之前,可以用Perl脚本autoscan从源文件中抽取与函数调用和头文件有关的信息,并将其输出到cofigure.scan文件中.
  autoscan的完整语法为:
  autoscan [ --macrodir=dir ] [ --help ] [ --verbose ] [ --version ] [srcdir ]
  它没有必须要求的参数.srcdir指定了扫描的目录.在大多数情况下,只在源代码树的根目录下执行autoscan就足够了. 但是,在将该文件重命名或复制到configure.in之前,需要手工检查一下以确认是否遗漏了需要抽取的特性.ifnames工具的功能与 autoscan类似,它查找源文件中的预处理指令#if,#elif,#ifdef和#ifndef.可以用它来增加autoscan的输出, ifname的语法是:
  Usage: ifnames [ -h ] [ --help ] [ -m dir ] [ --macrodir=dir ] [ --version ] [ file ... ]
  关键的参数是file ...,它是要
posted @ 2005-08-04 21:25 ivaneeo 阅读(190) | 评论 (0)编辑 收藏

代码清单 bogusapp.c
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_RESOLV_H
#include <resolv.h>
#endif /* HAVE_RESOLV_H */
#include "config.h"

int main(void)
{
    int reval;
#ifdef HAVE_MMAP
     fprintf(stdout, "have mmap()\n");
#else
     fprintf(stderr, "no mmap()\n");
#endif

if(HAVE_UTIME_NULL)
  fprintf(stdout, "utime() allows NULL\n");
else
  fprintf(stderr, "utime doesn't allow NULL\n");

if(SYS_SIGLIST_DECLARED)
  fprintf(stdout, "sys_siglist() declared\n");
else
  fprinf(stderr, "sys_siglist() not declared\n");

#ifdef HAVE_NCURSES_H
  fprintf(stdout, "ncurses.h found\n");
#else
  fprintf(stderr, "ncurses.h not found\n);

if(HAVE_FCNTL_H)
  fprintf(stdout, "fcntl.h found\n");
else
  fprintf(stderr, "fcntl.h not found\n");

if(HAVE_SYS_FCNTL_H)
  fprintf(stdout, "sys/fcntl.h found\n");
else
  fprintf(stderr, "sys/fcntl.h not found\n");

#ifdef NLIST_NAME_UNION
  fprintf(stdout, "nlist.n_un member found\n");
#else
  fprintf(stdout, "nlist.n_un member not found\n");
#endif

if(HAVE_VOID_POINTER)
  fprintf(stdout, "Yep, we have a usable void pointer type\n");
else
  fprintf(stderr, "Nope, no usable void pointer type\n");
exit(EXIT_SUCCESS);
}
.Makefiel.in--用于创建真正的makefile文件的模板
.acconfig.h--与特定系统相关的宏的集合,它随autoconf软件一起提供
.bogusapp.c--bogusapp的源代码,这是个示例程序
.config.h--包含bogusapp.c中用到的所有宏的头文件
.configure.in--创建最终的configure脚本的模板
.install.sh--安装脚本,用在不带兼容BSD的install程序的系统上

在目录下运行autoscan产生的configure.scan如下:
$autoscan
$cat configure.scan
dnl Process this file with autoconf to produce a configure script.
AC_INIT(acconfig.h)
dnl Checks for programs.
dnl Checks for libraries.
dnl Checks for header files.
AC_HEADER_STDC
dnl Checks for typedefs, structures, and compiler characteristics.
dnl Checks for library functions.
AC_OUTPUT(Makefile)

ifnames的输出如下:
HAVE_MMAP bogusapp.c
HAVE_NCURSES_H bogusapp.c
HAVE_RESOLV_H bogusapp.c
HAVE_NAME_UNION bogusapp.c
posted @ 2005-08-04 21:24 ivaneeo 阅读(317) | 评论 (0)编辑 收藏

                          候选程序测试集
测试                   说明
AC_PROG_AWK             顺序检查mawk,gawk,nawk和awk是否存在,将输出变量AWK设置为所找到的第一个程序名
AC_PROG_CC             决定使用哪个C编译器,并设置输出变量CC
AC_PROG_CC_C_O         决定编译器是否接受-c或-o选项,如果不接受,定义NO_MINUS_C_MINUS_O
AC_PROG_CPP            把输出变量CPP设置为执行C预处理的命令
AC_PROG_INSTALL        把输出变量INSTALL设置为BSD兼容的install程序,或者是install -sh
AC_PROG_LEX            查找flex或lex,并把输出变量LEX设为结果
AC_PROG_LN_S           如果系统支持符号链接,则设置变量LN_S设为ln -s,否则设置为ln
AC_PROG_RANLIB         如果ranlib存在,则设置输出变量RANLIB为ranlib,否则设置为":"
AC_PROG_YACC           顺序查找bison,byacc和yacc,并根据它找到结果把输出变量YACC设为bison -y,byacc或yacc

                       库函数测试集
测试                          说明
AC_CHECK_LIB(lib,function[   通过把一个C程序链接到函数库lib来判断在
,action_if_found[            lib库中是否存在指定的函数.在测试成功是
,action_if_not_found,        执行shell命令action_if_found或者在
[,other_libs]]])             ation_if_found为空时,在输出变量LIB中添
                             加-llib.action_if_not_found把           lother_libs选项传给link命令
AC_FUNC_GETLOADAVG           如果系统支持getloadavg函数,把获得该函数所必须的函数库添加到LIBS变量
AC_FUNC_GETPGRP               测试getprgrp是否需要参数,如果不需要,定义GETPGRP_VOID,否则,getpgrp 需要一个进程ID作为其参数
AC_FUNC_MEMCMP               如果memcmp函数不存在,把memcmp.o添加到LIBOBJS中
AC_FUNC_MMAP                 如果存在mmap函数,设置HAVE_MMAP
AC_FUNC_SETPGRP               测试setprgrp是否需要参数,如果不需要,定义SETPGRP_VOID,否则,setpgrp 需要两个进程ID作为其参数
AC_FUNC_UTIME_NULL           如果utime(file,NULL)函数能把文件的时间戳设置为当前时间,定义HAVE_UTIME_NULL
AC_FUNC_VFORK                 如果vfork.h文件不存在,定义vfork为fork
AC_FUNC_VPRINTF              如果存在vprintf函数,定义HAVE_VPRINTF
posted @ 2005-08-04 21:23 ivaneeo 阅读(251) | 评论 (0)编辑 收藏

                         头文件测试
测试                  说明
AC_DECL_SYS_SIGLIST   如果signal.h或unistd.h定义了sys_syglist,定义               SYS_SIGLIST_DECLARED
AC_HEADER_DIRENT      顺序检查头文件dirent.h, sysdir/ndir.h,sys/dir.h和ndir.h中是否定义了DIR,并根据结果定义HAVE_DIRENT_H, HAVE_SYS_NDIR_H,HAVE_SYS_DIR_H或HAVE_NDIR_H
AC_HEADER_STDC        如果系统支持ANSI/ISO C头文件,定义STDC_HEADERS
AC_HEADER_SYS_WAIT    如果系统支持有POSIX兼容的头文件sys/wait.h,定义输出变量HAVE_SYS_WAIT
posted @ 2005-08-04 21:23 ivaneeo 阅读(264) | 评论 (0)编辑 收藏

                        结构测试
测试                  说明
AC_HEADER_TIME        如果time.h和sys/time.h在一个程序中都存在,定义输出变量TIME_WITH_SYS_TIME
AC_STRUCT_ST_BLKSIZE  如果stat结构有成员st_blksize,定义输出变量                HAVE_ST_BLKSIZE
AC_STRUCT_ST_BLOCKS   如果stat结构有成员st_blocks,定义输出变量               HAVE_ST_BLOCKS
AC_STRUCT_TIMEZONE    指出如何取得时区值,如果tm结构有成员tm_zone,定义输出变量HAVE_TM_ZONE:如果找到tzname数组,定义输出变量HAVE_TZNAME
posted @ 2005-08-04 21:22 ivaneeo 阅读(194) | 评论 (0)编辑 收藏

                           类型定义测试
测试                     说明
AC_TYPE_GETGROUPS        根据传递给 getgroups()的数组的基本类型来设置              GETGROUPS_T为gid_t或int
AC_TYPE_MODE_T           如果mode_t没有定义,定义mode_t为int
AC_TYPE_PID_T            如果pid_t没有定义,定义pid_t为int
AC_TYPE_SIGNAL           如果signal.h中没有将signal定义为(void*),定义RETSIGTYPE为int
AC_TYPE_SIZE_T           如果size_t没有定义,定义size_t为unsigned
AC_TYPE_UID_T            如果uid_t没有定义,定义uid_t和gid_t为int
posted @ 2005-08-04 21:21 ivaneeo 阅读(179) | 评论 (0)编辑 收藏

仅列出标题
共67页: First 上一页 59 60 61 62 63 64 65 66 67 下一页