QEMU configure腳本內函數分析

QEMU configure腳本內函數分析

@(QEMU)[QEMU|configure]linux


[TOC]c++


前言

QEMU版本:2.5。shell

error_exit - 出錯結束函數

該函數用戶輸出錯誤信息,並結束腳本運行。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>。函數

do_compiler - 編譯函數

編譯。測試

參數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."

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
}
相關文章
相關標籤/搜索