@(QEMU)[QEMU|configure]linux
[TOC]c++
QEMU版本:2.5。shell
该函数用户输出错误信息,并结束脚本运行。ubuntu
参数1:错误信息。架构
参数...:【可选】错误补充说明。app
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>。函数
编译。测试
参数1:编译器。如:cc、c++、gcc、g++等。ui
参数...:编译选项。this
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."
使用"$cc"进行编译。
参数:编译选项。
do_cc() { do_compiler "$cc" "$@" }
使用"$cxx"进行编译。
参数:编译选项。
do_cxx() { do_compiler "$cxx" "$@" }
更新"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 }
该函数作了下面三个事情:
编译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。
编译可执行程序。
参数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。
用libtool编译程序。
建立软连接。"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" }
检查命令在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中搜索可执行程序是否存在。
参数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
不知道函数中的"$trace_backends"是什么东西。QEMU中的tracing使用多是介绍这个东西的。
have_backend () { echo "$trace_backends" | grep "$1" >/dev/null }
检查编译器的宏定义。
在该脚本中用于检查机器(如:linux、_WIN32等)和CPU架构(如:i386、x86_64、__arm__等)。
参数1:宏。
check_define() { cat > $TMPC <<EOF #if !defined($1) #error $1 not defined #endif int main(void) { return 0; } EOF compile_object }
参数1:头文件描述。如:stdlib.h、stdio.h等。
check_include() { cat > $TMPC <<EOF #include <$1> int main(void) { return 0; } EOF compile_object }
用于检测C编译器是否工做或作一些其余测试。
write_c_skeleton() { cat > $TMPC <<EOF int main(void) { return 0; } EOF }
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" "" }
当某个特性未找到时,会调用该函数输出这个问题,并输出解决办法,而后结束脚本运行。
参数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() { # 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)" }
upper() { echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]' }
参数1:要设置的配置。
disas_config() { echo "CONFIG_${1}_DIS=y" >> $config_target_mak echo "CONFIG_${1}_DIS=y" >> config-all-disas.mak }