QEMU configure脚本内函数分析

QEMU configure脚本内函数分析

@(QEMU)[QEMU|configure]


[TOC]


前言

QEMU版本:2.5。

error_exit - 出错结束函数

该函数用户输出错误信息,并结束脚本运行。

参数1:错误信息。

参数...:【可选】错误补充说明。

error_exit() {
    echo
    echo "ERROR: $1"
    while test -n "$2"; do
        echo "       $2"
        shift
    done
    echo
    exit 1
}

在该函数中使用了while+shift遍历参数并输出,该函数的参数个数可以是多个,如:error_exit <错误> <补充说明1> <补充说明2> <补充说明3>。

do_compiler - 编译函数

编译。

参数1:编译器。如:cc、c++、gcc、g++等。

参数...:编译选项。

do_compiler() {
    ......
}

下面对该函数进行分析。

将第一个参数保存到局部变量"compiler"中。然后执行shift命令对函数参数进行位移,第一个参数被丢弃。 "echo $compiler "$@" >> config.log"将编译命令输出到日志文件config.log中。代码:

    # Run the compiler, capturing its output to the log. First argument
    # is compiler binary to execute.
    local compiler="$1"
    shift

下面的第一条语句将编译命令输出到日志文件config.log中。第二条语句执行编译命令,并将编译输出和错误输出写入config.log文件中,如果编译失败则执行"return $?"。代码:

    echo $compiler "$@" >> config.log
    $compiler "$@" >> config.log 2>&1 || return $?

剩下的代码会检查是否需要添加"-Werror"编译选项,如果需要则添加"-Werror"编译选项后再次进行编译,如果编译失败则会调用error_exit函数输出错误信息。代码:

    # Test passed. If this is an --enable-werror build, rerun
    # the test with -Werror and bail out if it fails. This
    # makes warning-generating-errors in configure test code
    # obvious to developers.
    if test "$werror" != "yes"; then
        return 0
    fi
    # Don't bother rerunning the compile if we were already using -Werror
    case "$*" in
        *-Werror*)
           return 0
        ;;
    esac
    echo $compiler -Werror "$@" >> config.log
    $compiler -Werror "$@" >> config.log 2>&1 && return $?
    error_exit "configure test passed without -Werror but failed with -Werror." \
        "This is probably a bug in the configure script. The failing command" \
        "will be at the bottom of config.log." \
        "You can run configure with --disable-werror to bypass this check."

do_cc - 编译函数

使用"$cc"进行编译。

参数:编译选项。

do_cc() {
    do_compiler "$cc" "$@"
}

do_cxx - 编译函数

使用"$cxx"进行编译。

参数:编译选项。

do_cxx() {
    do_compiler "$cxx" "$@"
}

update_cxxflags - 更新cxxflags

更新"QEMU_CXXFLAGS"的值,过滤掉对一些GCC C++某些版本的编译器无用的编译器选项,因为那些选项只对C程序有意义。

update_cxxflags() {
    # Set QEMU_CXXFLAGS from QEMU_CFLAGS by filtering out those
    # options which some versions of GCC's C++ compiler complain about
    # because they only make sense for C programs.
    QEMU_CXXFLAGS=
    for arg in $QEMU_CFLAGS; do
        case $arg in
            -Wstrict-prototypes|-Wmissing-prototypes|-Wnested-externs|\
            -Wold-style-declaration|-Wold-style-definition|-Wredundant-decls)
                ;;
            *)
                QEMU_CXXFLAGS=${QEMU_CXXFLAGS:+$QEMU_CXXFLAGS }$arg
                ;;
        esac
    done
}

该函数做了下面三个事情:

  1. 在函数的开始处将"QEMU_CXXFLAGS"置空。
  2. 然后for循环遍历"QEMU_CFLAGS"中的值,并在for中过滤编译选项。
  3. 将未被过滤的编译选项追加到"QEMU_CXXFLAGS"中。

compile_object - 编译函数

编译object文件。

参数1:cflags编译选项。

compile_object() {
  local_cflags="$1"
  do_cc $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
}

该函数调用do_cc函数将$TMPC文件编译为$TMPO。

这个函数只将临时文件(即,$TMPC所代表的文件)编译为object文件,这个object文件也是一个临时文件,这个函数只用于编译测试。

编译选项:$QEMU_CFLAGS,$local_cflags。

compile_prog - 编译函数

编译可执行程序。

参数1:cflags编译选项。

参数2:ldflags编译选项。

compile_prog() {
  local_cflags="$1"
  local_ldflags="$2"
  do_cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags
}

该函数调用do_cc函数将$TMPC文件编译为$TMPE。

这个函数只将临时文件(即,$TMPC所代表的文件)编译为可执行文件,这个可执行文件也是一个临时文件,这个函数只用于编译测试。

编译选项:$QEMU_CFLAGS,$local_cflags,$LDFLAGS,$local_ldflags。

do_libtool和libtool_prog

用libtool编译程序。

symlink - 创建软链接

创建软链接。"ln -sf"的可移植版本。

参数1:原文件路径。

参数2:目标文件路径。

# symbolically link $1 to $2.  Portable version of "ln -sf".
symlink() {
  rm -rf "$2"
  mkdir -p "$(dirname "$2")"
  ln -s "$1" "$2"
}
  1. 无论目标文件是否存在,先删除。
  2. mkdir创建目标目录。
  3. 创建软链接。

has - 判断命令是否存在

检查命令在shell中是否可获得(可以用于判断一个內建命令,即,has可以判断出shell中是否定义了某个函数。如:在shell中定义了一个函数叫"abc",has可以判断出函数"abc"是存在的。可以判断一个非內建命令,如:ls、rm等。但has不能判断shell中是否存在某个变量)。

参数1:要判断的命令。

# check whether a command is available to this shell (may be either an
# executable or a builtin)
has() {
    type "$1" >/dev/null 2>&1
}

path_of - 从PATH中查找可执行程序

从PATH中搜索可执行程序是否存在。

参数1:可执行程序路径。这个路径可以是一个相对路径也可以是一个绝对路径。

返回值:如果可执行文件存在,则通过echo返回可执行程序的路径,否则不会调用echo返回字符串。

# search for an executable in PATH
path_of() {
    ......
}

局部变量初始化:

    local_command="$1"
    local_ifs="$IFS"
    local_dir=""

如果$local_command中有有目录字符(即,'/'字符),则"${local_command#*/}"与"$local_command"不会相等,那么就会进入if语句之内执行。内部的if语句会判断$local_command是否可执行,并且判断它是否不是目录,如果内部if判断为真,则echo会输出"$local_command"并且返回0。代码:

    # pathname has a dir component?
    if [ "${local_command#*/}" != "$local_command" ]; then
        if [ -x "$local_command" ] && [ ! -d "$local_command" ]; then
            echo "$local_command"
            return 0
        fi
    fi

如果"$local_command"字符串为空,则返回1:

    if [ -z "$local_command" ]; then
        return 1
    fi

遍历$PATH中的路径,将这些路径与"$local_command"结合,判断结合后的路径是否可执行并且是否不是目录,如果if判断为真,则echo会输出结合后的路径并返回0,否则返回1。代码:

    IFS=:
    for local_dir in $PATH; do
        if [ -x "$local_dir/$local_command" ] && [ ! -d "$local_dir/$local_command" ]; then
            echo "$local_dir/$local_command"
            IFS="${local_ifs:-$(printf ' \t\n')}"
            return 0
        fi
    done
    # not found
    IFS="${local_ifs:-$(printf ' \t\n')}"
    return 1

have_backend - 未知

不知道函数中的"$trace_backends"是什么东西。QEMU中的tracing使用可能是介绍这个东西的。

have_backend () {
    echo "$trace_backends" | grep "$1" >/dev/null
}

query_pkg_config

check_define - 检查编译器宏定义

检查编译器的宏定义。

在该脚本中用于检查机器(如:linux、_WIN32等)和CPU架构(如:i386x86_64、__arm__等)。

参数1:宏。

check_define() {
cat > $TMPC <<EOF
#if !defined($1)
#error $1 not defined
#endif
int main(void) { return 0; }
EOF
  compile_object
}

check_include - 检查是否可找到头文件

参数1:头文件描述。如:stdlib.h、stdio.h等。

check_include() {
cat > $TMPC <<EOF
#include <$1>
int main(void) { return 0; }
EOF
  compile_object
}

write_c_skeleton - 写C骨架

用于检测C编译器是否工作或做一些其他测试。

write_c_skeleton() {
    cat > $TMPC <<EOF
int main(void) { return 0; }
EOF
}

cc_has_warning_flag

cc_has_warning_flag() {
    write_c_skeleton;

    # Use the positive sense of the flag when testing for -Wno-wombat
    # support (gcc will happily accept the -Wno- form of unknown
    # warning options).
    optflag="$(echo $1 | sed -e 's/^-Wno-/-W/')"
    compile_prog "-Werror $optflag" ""
}

feature_not_found - 特性未找到

当某个特性未找到时,会调用该函数输出这个问题,并输出解决办法,然后结束脚本运行。

参数1:特性。

参数2:解决办法。

feature_not_found() {
  feature=$1
  remedy=$2

  error_exit "User requested feature $feature" \
      "configure was not able to find it." \
      "$remedy"
}

gnutls_works - 判断是否支持gnutls

gnutls_works() {
    # Unfortunately some distros have bad pkg-config information for gnutls
    # such that it claims to exist but you get a compiler error if you try
    # to use the options returned by --libs. Specifically, Ubuntu for --static
    # builds doesn't work:
    # https://bugs.launchpad.net/ubuntu/+source/gnutls26/+bug/1478035
    #
    # So sanity check the cflags/libs before assuming gnutls can be used.
    if ! $pkg_config --exists "gnutls"; then
        return 1
    fi

    write_c_skeleton
    compile_prog "$($pkg_config --cflags gnutls)" "$($pkg_config --libs gnutls)"
}

has_libgcrypt_config - 检查是否有libgcrypt-config

audio_drv_probe

upper - 将所有小写字母转换为大写字母

upper() {
    echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
}

disas_config - 设置配置

参数1:要设置的配置。

disas_config() {
  echo "CONFIG_${1}_DIS=y" >> $config_target_mak
  echo "CONFIG_${1}_DIS=y" >> config-all-disas.mak
}

转载于:https://my.oschina.net/ibuwai/blog/657367

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值