@(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 }