一、必要性

作为源代码发行的软件,希望在尽可能多的环境上可以运行,这些环境包括了操作系统的类型,硬件系统、开发环境的不同的方面;另一方面,在Linux系统中没有一种统一的位置可以确定系统中是否支持某种功能,例如:无 法确认这个系统是否安装了gcc工具,它的位置在哪里,该操作系统是否支持mmap功能、甚至是环境是大端字节序还是小端字节序等属性,所以需要通过执行 configure来动态的尝试确定源代码构建和运行环境需要的属性情况。最重要的目的是替换Makefile中的指定变量

二、各种配置文件说明

configure.ac

configure 这个是我们需要监测环境的主要入口文件,使用该文件可以生成Makefile文件,它会替换Makefile中需要替换的变量。

config.guess

config.sub

config.log

congfigure.status

config.cache

三、主要功能实现

1、config.sub

它主要是将配置环境转换为三元组或者四元组。其核心代码为

# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
  knetbsd*-gnu* | netbsd*-gnu* | \
  kopensolaris*-gnu* | \
  storm-chaos* | os2-emx* | rtmk-nova*)
    os=-$maybe_os所有最后两项是 KERNEL-OS类型的配置输出落入该分支。例如powerpc-linux-gnu,其它的执行下面的一个分支。
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
    ;;
  *)
    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
    if [ $basic_machine != $1 ]
    then os=`echo $1 | sed 's/.*-/-/'`最后一个-为OS类型,之前的所有均为机器类型。例如powerpc-linux,powerpc-IBM-linux,
    else os=; fi
    ;;
esac

2、configure中对环境的替换

ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
$as_echo "$ac_cv_build" >&6; }
case $ac_cv_build in
*-*-*) ;;
*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
esac
build=$ac_cv_build
ac_save_IFS=$IFS; IFS='-'
set x $ac_cv_build
shift
build_cpu=$1
build_vendor=$2
shift; shift
# Remember, the first character of IFS is used to create $*,
# except with old shells:
build_os=$*

这些变量一般是底层的Makefile需要替换的变量,并根据这些变量定义一些宏值,或者执行一些特殊配置。

3、cache文件的使用和处理

可以通过命令行中 --cache-file=来进行设置

-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    cache_file=$ac_optarg ;;…………
if test -r "$cache_file"; then
  # Some versions of bash will fail to source /dev/null (special
  # files actually), so we avoid doing that.
  if test -f "$cache_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
$as_echo "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . "$cache_file";;
      *)                    . "./$cache_file";; 执行cache文件。
    esac
  fi
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi

其中cache文件中变量的值统一以 ac_av_前缀开始,这个约定大家要注意一下,其中分别代表AutoConfigure AutoValue

4、config.status

从configure可以看出,在该文件的最后,很多的代码都是用来项这个文件添加内容的,所以也就是说这个文件的内容是M4动态生成的,我们知道的作用就好了,该文件通过CONFIG_STATUS 变量进行引用。从使用上看,我们也可以定义同名的宏覆盖这个文件名。

5、config.log的使用

cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.It was created by $as_me, which was
generated by GNU Autoconf 2.64.  Invocation command line was  $ $0 $@
_ACEOF
exec 5>>config.log

直接把文件的第五项文件描述符定向到config.log,从而之后所有项5号文件描述符输出的内容都将会放在config.log文件中。

6、其它使用的一些命令

sed 的 t 命令,这个在configure的最后有使用。根据说明文档,它的作用是前面的一个sed的substitute命令如果成功的话,就跳转到t后面的标 签,这个主要是为了进行递归处理,如果一个变量替换之后还需要替换,那么就可以使用这个命令。它常用在匹配的环境中,例如() @@等。这个可以认为是最为原始的一个条件跳转,configure中使用的是 t  t ,其中 t也是一个label的位置

b 命令这个是一个无条件跳转,一般在一个匹配条件之后或者一个无条件跳转,如果不指定label,则跳转到文件结束。

; 这个是为了支持一行可以有多个sed命令而设置的命令,就像cmd中的&和bash中的;一样。

expr 命令,这 个是Linux下的一个标准命令,它可以进行简单的算数运算,重要的是它还可以进行字符串的匹配运算,这一点是通常的算数表达式不具备的特征。在bash 的源代码中哟一个expr.c,但是注意这个不是一个bash的内置命令,它只是给bash的eval调用的一个工具文件