• eosio_build.sh 执行过程


    eosio_build.sh

    打开eos目录结构,eosio_build.sh在 eos/scripts目录下

    1.定义usage方法,该方法在cli执行出错时打印出来,

    function usage() {
       printf "Usage: $0 OPTION...
      -P          Build with pinned clang and libcxx
      -o TYPE     Build <Debug|Release|RelWithDebInfo|MinSizeRel> (default: Release)
      -s NAME     Core Symbol Name <1-7 characters> (default: SYS)
      -b DIR      Use pre-built boost in DIR
      -i DIR      Directory to use for installing dependencies & EOSIO (default: $HOME)
      -y          Noninteractive mode (answers yes to every prompt)
      -c          Enable Code Coverage
      -d          Generate Doxygen
      -m          Build MongoDB dependencies
       \n" "$0" 1>&2
       exit 1
    }

    2.设置执行时间

    # 开始时间,获取从1970年至现在的秒数
    TIME_BEGIN=$( date -u +%s )

    3.验证options#判断输入参数不为0

    if [ $# -ne 0 ]; then
      # 参数循环验证
       while getopts "o:s:b:i:ycdhmPf" opt; do
    #case选项匹配 case "${opt}" in o )
    # 构建执行选项集合 options
    =( "Debug" "Release" "RelWithDebInfo" "MinSizeRel" ) # 如果匹配到options中的一个,则将CMAKE_BUILD_TYPE设置到该选项 if [[ "${options[*]}" =~ "${OPTARG}" ]]; then CMAKE_BUILD_TYPE=$OPTARG else # 不匹配,输出错误 echo "Invalid argument: ${OPTARG}" 1>&2
    # 调用usage方法
    usage fi ;; s ) # 如果OPTARG值不在1~7或者optage为空,输出错误,执行usage方法 if [ "${#OPTARG}" -gt 7 ] || [ -z "${#OPTARG}" ]; then echo "Invalid argument: ${OPTARG}" 1>&2 usage else
    #定义变量为设置环境变量CORE_SYMBOL_NAME
    CORE_SYMBOL_NAME=$OPTARG fi ;; b )
    BOOST_LOCATION
    =$OPTARG ;; i ) INSTALL_LOCATION=$OPTARG ;; y ) NONINTERACTIVE=true PROCEED=true ;; f ) echo "DEPRECATION NOTICE: -f will be removed in the next release..." ;; # Needs to be removed in 1.9 c ) ENABLE_COVERAGE_TESTING=true ;; d ) ENABLE_DOXYGEN=true ;; m ) ENABLE_MONGO=true ;; P ) PIN_COMPILER=true ;; h ) usage ;; ? ) echo "Invalid Option!" 1>&2 usage ;; : ) echo "Invalid Option: -${OPTARG} requires an argument." 1>&2 usage ;; * ) usage ;; esac done fi

    3.将当前工作路径设置为环境变量

    export CURRENT_WORKING_DIR=$(pwd) 

    4.切换到上级目录也就是项目目录

    cd $( dirname "${BASH_SOURCE[0]}" )/..

    5.加载eosio特定的辅助函数

    . ./scripts/helpers/eosio.sh

    -->现在深入了解下eosio.sh

    首先是这段代码

    [[ -z "${ARCH}" ]] && export ARCH=$( uname )
    if [[ -z "${NAME}" ]]; then
        if [[ $ARCH == "Linux" ]]; then
            [[ ! -e /etc/os-release ]] && echo "${COLOR_RED} - /etc/os-release not found! It seems you're attempting to use an unsupported Linux distribution.${COLOR_NC}" && exit 1
            # Obtain OS NAME, and VERSION
            . /etc/os-release
        elif [[ $ARCH == "Darwin" ]]; then export NAME=$(sw_vers -productName)
        else echo " ${COLOR_RED}- EOSIO is not supported for your Architecture!${COLOR_NC}" && exit 1
        fi
    fi
    
    # Setup yum and apt variables
    if [[ $NAME =~ "Amazon Linux" ]] || [[ $NAME == "CentOS Linux" ]]; then
        if ! YUM=$( command -v yum 2>/dev/null ); then echo "${COLOR_RED}YUM must be installed to compile EOSIO${COLOR_NC}" && exit 1; fi
    elif [[ $NAME == "Ubuntu" ]]; then
        if ! APTGET=$( command -v apt-get 2>/dev/null ); then echo "${COLOR_RED}APT-GET must be installed to compile EOSIO${COLOR_NC}" && exit 1; fi
    fi

    上述代码主要功能是验证操作系统,根据不同的操作系统设置不同的NAME环境变量

    接着这段代码,设置eos必须的环境变量

    . ./scripts/.environment
    .environment内容如下
    export SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    export REPO_ROOT="${SCRIPT_DIR}/.."
    export BUILD_DIR="${REPO_ROOT}/build"
    
    export EOSIO_VERSION_MAJOR=$(cat $REPO_ROOT/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*([[:blank:]]*VERSION_MAJOR" | tail -1 | sed 's/.*VERSION_MAJOR //g' | sed 's/ //g' | sed 's/"//g' | cut -d) -f1)
    export EOSIO_VERSION_MINOR=$(cat $REPO_ROOT/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*([[:blank:]]*VERSION_MINOR" | tail -1 | sed 's/.*VERSION_MINOR //g' | sed 's/ //g' | sed 's/"//g' | cut -d) -f1)
    export EOSIO_VERSION_PATCH=$(cat $REPO_ROOT/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*([[:blank:]]*VERSION_PATCH" | tail -1 | sed 's/.*VERSION_PATCH //g' | sed 's/ //g' | sed 's/"//g' | cut -d) -f1)
    export EOSIO_VERSION_SUFFIX=$(cat $REPO_ROOT/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*([[:blank:]]*VERSION_SUFFIX" | tail -1 | sed 's/.*VERSION_SUFFIX //g' | sed 's/ //g' | sed 's/"//g' | cut -d) -f1)
    export EOSIO_VERSION="${EOSIO_VERSION_MAJOR}.${EOSIO_VERSION_MINOR}"
    if [[ -z $EOSIO_VERSION_SUFFIX ]]; then
        export EOSIO_VERSION_FULL="${EOSIO_VERSION_MAJOR}.${EOSIO_VERSION_MINOR}.${EOSIO_VERSION_PATCH}"
    else
        export EOSIO_VERSION_FULL="${EOSIO_VERSION_MAJOR}.${EOSIO_VERSION_MINOR}.${EOSIO_VERSION_PATCH}-${EOSIO_VERSION_SUFFIX}"
    fi
    
    export CMAKE_REQUIRED_VERSION=$(cat $REPO_ROOT/CMakeLists.txt | grep -E "^[[:blank:]]*cmake_minimum_required[[:blank:]]*([[:blank:]]*VERSION" | tail -1 | sed 's/.*VERSION //g' | sed 's/ //g' | sed 's/"//g' | cut -d) -f1)
    
    export EOSIO_INSTALL_DIR="${HOME}/eosio/${EOSIO_VERSION}"
    export TEMP_DIR="${TEMP_DIR:-${HOME}/tmp}"
    
    [[ -f ${BUILD_DIR}/CMakeCache.txt ]] && export CACHED_INSTALL_PATH=$(grep "CMAKE_INSTALL_PREFIX:PATH" ${BUILD_DIR}/CMakeCache.txt | cut -d= -f2)
    #执行.build_vars,设置环境变量
    . ./scripts/.build_vars
    .build_vars代码,
    # See install-directory-prompt for logic that sets EOSIO_INSTALL_DIR
    export SRC_DIR=${EOSIO_INSTALL_DIR}/src
    export OPT_DIR=${EOSIO_INSTALL_DIR}/opt
    export VAR_DIR=${EOSIO_INSTALL_DIR}/var
    export ETC_DIR=${EOSIO_INSTALL_DIR}/etc
    export BIN_DIR=${EOSIO_INSTALL_DIR}/bin
    export LIB_DIR=${EOSIO_INSTALL_DIR}/lib
    export DATA_DIR=${EOSIO_INSTALL_DIR}/data
    
    # CMAKE
    export CMAKE_VERSION_MAJOR=3
    export CMAKE_VERSION_MINOR=13
    export CMAKE_VERSION_PATCH=2
    export CMAKE_VERSION=${CMAKE_VERSION_MAJOR}.${CMAKE_VERSION_MINOR}.${CMAKE_VERSION_PATCH}
    
    # MONGO
    export MONGODB_VERSION=3.6.3
    export MONGODB_ROOT=${OPT_DIR}/mongodb-${MONGODB_VERSION}
    export MONGODB_BIN=${BIN_DIR}/mongod
    export MONGODB_CONF=${ETC_DIR}/mongod.conf
    export MONGODB_LOG_DIR=${VAR_DIR}/log/mongodb
    export MONGODB_LINK_DIR=${OPT_DIR}/mongodb
    export MONGODB_DATA_DIR=${DATA_DIR}/mongodb
    export MONGO_C_DRIVER_VERSION=1.13.0
    export MONGO_C_DRIVER_ROOT=${SRC_DIR}/mongo-c-driver-${MONGO_C_DRIVER_VERSION}
    export MONGO_CXX_DRIVER_VERSION=3.4.0
    export MONGO_CXX_DRIVER_ROOT=${SRC_DIR}/mongo-cxx-driver-r${MONGO_CXX_DRIVER_VERSION}
    export ENABLE_MONGO=${ENABLE_MONGO:-false}
    export INSTALL_MONGO=${INSTALL_MONGO:-false}
    
    # BOOST
    export BOOST_VERSION_MAJOR=1
    export BOOST_VERSION_MINOR=70
    export BOOST_VERSION_PATCH=0
    export BOOST_VERSION=${BOOST_VERSION_MAJOR}_${BOOST_VERSION_MINOR}_${BOOST_VERSION_PATCH}
    export BOOST_ROOT=${BOOST_LOCATION:-${SRC_DIR}/boost_${BOOST_VERSION}}
    export BOOST_LINK_LOCATION=${OPT_DIR}/boost
    
    # LLVM
    export LLVM_VERSION=release_40
    export LLVM_ROOT=${OPT_DIR}/llvm
    export LLVM_DIR=${LLVM_ROOT}/lib/cmake/llvm
    
    # DOXYGEN
    export DOXYGEN_VERSION=1_8_14
    export DOXYGEN_ROOT=${SRC_DIR}/doxygen-${DOXYGEN_VERSION}
    export ENABLE_DOXYGEN=${ENABLE_DOXYGEN:-false}
    
    # CLANG
    export CLANG_ROOT=${OPT_DIR}/clang8
    export PINNED_COMPILER_BRANCH=release_80
    export PINNED_COMPILER_LLVM_COMMIT=18e41dc
    export PINNED_COMPILER_CLANG_COMMIT=a03da8b
    export PINNED_COMPILER_LLD_COMMIT=d60a035
    export PINNED_COMPILER_POLLY_COMMIT=1bc06e5
    export PINNED_COMPILER_CLANG_TOOLS_EXTRA_COMMIT=6b34834
    export PINNED_COMPILER_LIBCXX_COMMIT=1853712
    export PINNED_COMPILER_LIBCXXABI_COMMIT=d7338a4
    export PINNED_COMPILER_LIBUNWIND_COMMIT=57f6739
    export PINNED_COMPILER_COMPILER_RT_COMMIT=5bc7979
    export NO_CPP17=${NO_CPP17:-false}
    export PIN_COMPILER=${PIN_COMPILER:-false}
    export BUILD_CLANG=${BUILD_CLANG:-false}
    
    export CORE_SYMBOL_NAME=${CORE_SYMBOL_NAME:-SYS}
    
    export CPU_CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
    export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Release}
    
    export NONINTERACTIVE=${NONINTERACTIVE:-false}
    export PROCEED=${PROCEED:-false}
    
    export CURRENT_USER=${CURRENT_USER:-$(whoami)}
    
    export ENABLE_COVERAGE_TESTING=${ENABLE_COVERAGE_TESTING:-false}
    export HOMEBREW_NO_AUTO_UPDATE=1
    export TINI_VERSION=0.18.0
    export DISK_MIN=5
    export COUNT=0
    export DRYRUN=${DRYRUN:-false}
    export VERBOSE=${VERBOSE:-false}
    export SUDO_LOCATION=$( command -v sudo )

    从environment和build.vars可知,上述都是eosio必须的系统变量,后续可以直接根据系统变量执行相应的函数

    回到eosio.sh,接下来执行

    . ./scripts/helpers/general.sh

    general.sh内部主要分为两类,最开始代码为

    # 如果是交互式模式
    if [[ $- == *i* ]]; then # Disable if the shell isn't interactive (avoids: tput: No value for $TERM and no -T specified)
      export COLOR_NC=$(tput sgr0) # No Color
      export COLOR_RED=$(tput setaf 1)
      export COLOR_GREEN=$(tput setaf 2)
      export COLOR_YELLOW=$(tput setaf 3)
      export COLOR_BLUE=$(tput setaf 4)
      export COLOR_MAGENTA=$(tput setaf 5)
      export COLOR_CYAN=$(tput setaf 6)
      export COLOR_WHITE=$(tput setaf 7)
    fi

    该代码是在交互式模式下进行环境变量声明,后面的代码都是一些函数定义,因为在eosio_build.sh会在general用到(ensure-sudo、ensure-git-clone)这2个函数,所以目前我们只对这几个函数进行分析

    查看代码:

    ensure-sudo:确保是root用户或者是普通用户根据sudo进行root授权执行

    function ensure-sudo() {
      ( [[ $CURRENT_USER != "root" ]] && [[ -z $SUDO_LOCATION ]] ) && echo "${COLOR_RED}Please install the 'sudo' command before proceeding!${COLOR_NC}" && exit 1
      true 1>/dev/null # Needed
    }
    ensure-git-clone:确保是git代码
    function ensure-git-clone() {
      if [[ ! -e "${REPO_ROOT}/.git" ]]; then
        echo "This build script only works with sources cloned from git"
        exit 1
      fi
    }

    回到eosio.sh,接下来也是一系列函数,这里也只关注eosio_build.sh所需的函数(ensure-which,install-directory-prompt,previous-install-prompt,prompt-mongo-install,setup)

    ensure-which

     1 function ensure-which() {
     2  //如果未安装which命令
     3   if ! which ls &>/dev/null; then
     4     while true; do
     5       [[ $NONINTERACTIVE == false ]] && printf "${COLOR_YELLOW}EOSIO compiler checks require the 'which' package: Would you like for us to install it? (y/n)?${COLOR_NC}" && read -p " " PROCEED
     6       echo ""
     7       case $PROCEED in
     8           "" ) echo "What would you like to do?";;
     9           0 | true | [Yy]* ) install-package which WETRUN; break;;
    10           1 | false | [Nn]* ) echo "${COLOR_RED}Please install the 'which' command before proceeding!${COLOR_NC}"; exit 1;;
    11           * ) echo "Please type 'y' for yes or 'n' for no.";;
    12       esac
    13     done
    14   fi
    15 }

    该方法是确保linux有which命令,如果没有,则根据选择是否安装which命令,安装which命令,关键代码在第10行这段代码

    install-package which WETRUN;

    其中install-package是通用方法,方法在general.sh中

     1 function install-package() {
     2   if [[ $ARCH == "Linux" ]]; then
     3     EXECUTION_FUNCTION="execute"
     4     [[ $2 == "WETRUN" ]] && EXECUTION_FUNCTION="execute-always"
     5     ( [[ $2 =~ "--" ]] || [[ $3 =~ "--" ]] ) && OPTIONS="${2}${3}"
     6     [[ $CURRENT_USER != "root" ]] && [[ ! -z $SUDO_LOCATION ]] && NEW_SUDO_COMMAND="$SUDO_LOCATION -E"
     7     ( [[ $NAME =~ "Amazon Linux" ]] || [[ $NAME == "CentOS Linux" ]] ) && eval $EXECUTION_FUNCTION $NEW_SUDO_COMMAND $YUM $OPTIONS install -y $1
     8     ( [[ $NAME =~ "Ubuntu" ]] ) && eval $EXECUTION_FUNCTION $NEW_SUDO_COMMAND $APTGET $OPTIONS install -y $1
     9   fi
    10   true # Required; Weird behavior without it
    11 }

    仔细分析install-package方法第4行和install-package which WETRUN命令,知道

    EXECUTION_FUNCTION="execute-always"

    然后分析第6行,验证root用户和root权限用户,第7、8行主要时构建安装命令以及执行安装命令,

    eval作用:可读取一连串的参数,然后再依参数本身的特性来执行

    如果不是root用户,则 Amazon Linux或CentOS Linux eval命令如下

    execute-always /usr/bin/sudo -E yum install -y which

    ubuntu系统安装命令如下

    execute-always /usr/bin/sudo -E yum apt-get -y which

    其中 execute-always,方法也在general.sh中,代码如下

     1 function execute-always() {
     2   ORIGINAL_DRYRUN=$DRYRUN
     3   DRYRUN=false
     4   execute "$@"
     5   DRYRUN=$ORIGINAL_DRYRUN
     6 }
     7 
     8 function execute() {
     9   $VERBOSE && echo "--- Executing: $@"
    10   $DRYRUN || "$@"
    11 }

    这里也把内部执行方法execute贴出来,这里时作一些准备工作,主要时必要时打印参数

    接着分析install-directory-prompt方法,代码如下

    function install-directory-prompt() {
        if [[ -z $INSTALL_LOCATION ]]; then
            echo "No installation location was specified. Please provide the location where EOSIO is installed."
            while true; do
                [[ $NONINTERACTIVE == false ]] && printf "${COLOR_YELLOW}Do you wish to use the default location? ${EOSIO_INSTALL_DIR}? (y/n)${COLOR_NC}" && read -p " " PROCEED
                echo ""
                case $PROCEED in
                    "" )
                    echo "What would you like to do?";;
                    0 | true | [Yy]* )
                    break;;
                    1 | false | [Nn]* )
                    printf "Enter the desired installation location." && read -p " " EOSIO_INSTALL_DIR;
                    export EOSIO_INSTALL_DIR;
                    break;;
                    * ) echo "Please type 'y' for yes or 'n' for no.";;
                esac
            done
        else
            # 这里时支持相对路径
            [[ ! $INSTALL_LOCATION =~ ^/ ]] && export INSTALL_LOCATION="${CURRENT_WORKING_DIR}/$INSTALL_LOCATION"
            export EOSIO_INSTALL_DIR="$INSTALL_LOCATION"
        fi
        . ./scripts/.build_vars
        echo "EOSIO will be installed to: ${EOSIO_INSTALL_DIR}"
    }

    该 方法时设置EOSIO安装目录,可以使用默认安装目录,也可以自定义安装目录。然后重新设置.build_vars中的环境变量

    previous-install-promp:安装确认

    function  previous-install-prompt() {
      if [[ -d $EOSIO_INSTALL_DIR ]]; then
        echo "EOSIO has already been installed into ${EOSIO_INSTALL_DIR}... It's suggested that you eosio_uninstall.sh before re-running this script."
        while true; do
          [[ $NONINTERACTIVE == false ]] && printf "${COLOR_YELLOW}Do you wish to proceed anyway? (y/n)${COLOR_NC}" && read -p " " PROCEED
          echo ""
          case $PROCEED in
            "" ) echo "What would you like to do?";;
            0 | true | [Yy]* ) break;;
            1 | false | [Nn]* ) exit;;
            * ) echo "Please type 'y' for yes or 'n' for no.";;
          esac
          done
      fi
    }

    promp-mongo-install:mongo db安装确认

    function prompt-mongo-install() {
        if $ENABLE_MONGO; then
            while true; do
                [[ $NONINTERACTIVE == false ]] && printf "${COLOR_YELLOW}You have chosen to include MongoDB support. Do you want for us to install MongoDB as well? (y/n)?${COLOR_NC}" && read -p " " PROCEED
                echo ""
                case $PROCEED in
                    "" ) echo "What would you like to do?";;
                    0 | true | [Yy]* ) export INSTALL_MONGO=true; break;;
                    1 | false | [Nn]* ) echo "${COLOR_RED} - Existing MongoDB will be used.${COLOR_NC}"; break;;
                    * ) echo "Please type 'y' for yes or 'n' for no.";;
                esac
            done
        fi
    }

    setup:创建安装目录

    function setup() {
    #打印待创建目录信息
    if $VERBOSE; then echo "VERBOSE: ${VERBOSE}" echo "DRYRUN: ${DRYRUN}" echo "TEMP_DIR: ${TEMP_DIR}" echo "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}" echo "CORE_SYMBOL_NAME: ${CORE_SYMBOL_NAME}" echo "BOOST_LOCATION: ${BOOST_LOCATION}" echo "INSTALL_LOCATION: ${INSTALL_LOCATION}" echo "BUILD_DIR: ${BUILD_DIR}" echo "EOSIO_INSTALL_DIR: ${EOSIO_INSTALL_DIR}" echo "NONINTERACTIVE: ${NONINTERACTIVE}" echo "PROCEED: ${PROCEED}" echo "ENABLE_COVERAGE_TESTING: ${ENABLE_COVERAGE_TESTING}" echo "ENABLE_DOXYGEN: ${ENABLE_DOXYGEN}" echo "ENABLE_MONGO: ${ENABLE_MONGO}" echo "INSTALL_MONGO: ${INSTALL_MONGO}" echo "SUDO_LOCATION: ${SUDO_LOCATION}" echo "PIN_COMPILER: ${PIN_COMPILER}" fi
    #如果有删除旧的build目录 ( [[ -d $BUILD_DIR ]] && [[ -z $BUILD_DIR_CLEANUP_SKIP ]] ) && execute rm -rf $BUILD_DIR # cleanup old build directory; support disabling it (Zach requested) execute-always mkdir -p $TEMP_DIR execute mkdir -p $BUILD_DIR execute mkdir -p $SRC_DIR execute mkdir -p $OPT_DIR execute mkdir -p $VAR_DIR execute mkdir -p $BIN_DIR execute mkdir -p $VAR_DIR/log execute mkdir -p $ETC_DIR execute mkdir -p $LIB_DIR if $ENABLE_MONGO; then execute mkdir -p $MONGODB_LOG_DIR execute mkdir -p $MONGODB_DATA_DIR fi }

    创建目录参考.build.vars

    # See install-directory-prompt for logic that sets EOSIO_INSTALL_DIR
    export SRC_DIR=${EOSIO_INSTALL_DIR}/src
    export OPT_DIR=${EOSIO_INSTALL_DIR}/opt
    export VAR_DIR=${EOSIO_INSTALL_DIR}/var
    export ETC_DIR=${EOSIO_INSTALL_DIR}/etc
    export BIN_DIR=${EOSIO_INSTALL_DIR}/bin
    export LIB_DIR=${EOSIO_INSTALL_DIR}/lib
    export DATA_DIR=${EOSIO_INSTALL_DIR}/data
    
    export MONGODB_LOG_DIR=${VAR_DIR}/log/mongodb
    export MONGODB_DATA_DIR=${DATA_DIR}/mongodb

    检查git文件是否存在

    function ensure-git-clone() {
      if [[ ! -e "${REPO_ROOT}/.git" ]]; then
        echo "This build script only works with sources cloned from git"
        exit 1
      fi
    }

    回到eosio_build.sh,接下来 的代码是

    # 打印版本,eos版本,日期,当前用户,git分支等
    $VERBOSE && echo "Build Script Version: ${SCRIPT_VERSION}" echo "EOSIO Version: ${EOSIO_VERSION_FULL}" echo "$( date -u )" echo "User: ${CURRENT_USER}" # echo "git head id: %s" "$( cat .git/refs/heads/master )" echo "Current branch: $( execute git rev-parse --abbrev-ref HEAD 2>/dev/null )" # 如果是ubuntu或者是darwin系统,则 ( [[ ! $NAME == "Ubuntu" ]] && [[ ! $ARCH == "Darwin" ]] ) && set -i # Ubuntu doesn't support interactive mode since it uses dash + Some folks are having this issue on Darwin; colors aren't supported yet anyway # 从之前的函数介绍,可以知道调用的方法内部逻辑 # 使用sudo调用root权限 ensure-sudo # 如果没有which命令,则安装 ensure-which # 防止运行非git克隆 ensure-git-clone # 提示用户安装路径install-directory-prompt #验证相同版本安装 previous-install-prompt # 是否安装mongo prompt-mongo-install # 设置目录和必须的环境 setup
    #切换到项目目录
    execute cd $REPO_ROOT

    # 验证子模块是否更新
    ensure-submodules-up-to-date
    验证cmake是否安装,安装是否符合安装版本(3.8)
    ( [[ -z "${CMAKE}" ]] && [[ ! -z $(command -v cmake 2>/dev/null) ]] ) && export CMAKE=$(command -v cmake 2>/dev/null) && export CMAKE_CURRENT_VERSION=$($CMAKE --version | grep -E "cmake version[[:blank:]]*" | sed 's/.*cmake version //g')
    # If it exists, check that it's > required version + 
    if [[ ! -z $CMAKE_CURRENT_VERSION ]] && [[ $((10#$( echo $CMAKE_CURRENT_VERSION | awk -F. '{ printf("%03d%03d%03d
    ", $1,$2,$3); }' ))) -lt $((10#$( echo $CMAKE_REQUIRED_VERSION | awk -F. '{ printf("%03d%03d%03d
    ", $1,$2,$3); }' ))) ]]; then
       export CMAKE=
       if [[ $ARCH == 'Darwin' ]]; then
          echo "${COLOR_RED}The currently installed cmake version ($CMAKE_CURRENT_VERSION) is less than the required version ($CMAKE_REQUIRED_VERSION). Cannot proceed."
          exit 1
       else
          echo "${COLOR_YELLOW}The currently installed cmake version ($CMAKE_CURRENT_VERSION) is less than the required version ($CMAKE_REQUIRED_VERSION). We will be installing $CMAKE_VERSION.${COLOR_NC}"
       fi
    fi

    接下来是安装特定的操作系统进行build(build内容之后再介绍)

    if [[ $ARCH == "Linux" ]]; then
       export CMAKE=${CMAKE:-${EOSIO_INSTALL_DIR}/bin/cmake}
       OPENSSL_ROOT_DIR=/usr/include/openssl
       [[ ! -e /etc/os-release ]] && print_supported_linux_distros_and_exit
       case $NAME in
          "Amazon Linux AMI" | "Amazon Linux")
             echo "${COLOR_CYAN}[Ensuring YUM installation]${COLOR_NC}"
             FILE="${REPO_ROOT}/scripts/eosio_build_amazonlinux.sh"
          ;;
          "CentOS Linux")
             FILE="${REPO_ROOT}/scripts/eosio_build_centos.sh"
          ;;
          "Ubuntu")
             FILE="${REPO_ROOT}/scripts/eosio_build_ubuntu.sh"
          ;;
          *) print_supported_linux_distros_and_exit;;
       esac
       CMAKE_PREFIX_PATHS="${EOSIO_INSTALL_DIR}"
    fi
    
    if [ "$ARCH" == "Darwin" ]; then
       # opt/gettext: cleos requires Intl, which requires gettext; it's keg only though and we don't want to force linking: https://github.com/EOSIO/eos/issues/2240#issuecomment-396309884
       # EOSIO_INSTALL_DIR/lib/cmake: mongo_db_plugin.cpp:25:10: fatal error: 'bsoncxx/builder/basic/kvp.hpp' file not found
       CMAKE_PREFIX_PATHS="/usr/local/opt/gettext;${EOSIO_INSTALL_DIR}"
       FILE="${SCRIPT_DIR}/eosio_build_darwin.sh"
       OPENSSL_ROOT_DIR=/usr/local/opt/openssl
       export CMAKE=${CMAKE}
    fi

    在pinned_toolchain中查找并替换OPT_DIR.cmake,然后将其移动到build dir

    execute bash -c "sed -e 's~@~$OPT_DIR~g' $SCRIPT_DIR/pinned_toolchain.cmake &> $BUILD_DIR/pinned_toolchain.cmake"

    其中pinned_toolchain.cmake内容如下:

    # 赋值变量
    set(OPT_PATH @) set(CMAKE_C_COMPILER_WORKS
    1) set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_C_COMPILER ${OPT_PATH}/clang8/bin/clang) set(CMAKE_CXX_COMPILER ${OPT_PATH}/clang8/bin/clang++) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${OPT_PATH}/clang8/include/c++/v1 /usr/local/include /usr/include) set(CMAKE_CXX_FLAGS_INIT "-nostdinc++") set(CMAKE_EXE_LINKER_FLAGS_INIT "-stdlib=libc++ -nostdlib++") set(CMAKE_SHARED_LINKER_FLAGS_INIT "-stdlib=libc++ -nostdlib++") set(CMAKE_MODULE_LINKER_FLAGS_INIT "-stdlib=libc++ -nostdlib++") set(CMAKE_CXX_STANDARD_LIBRARIES "${OPT_PATH}/clang8/lib/libc++.a ${OPT_PATH}/clang8/lib/libc++abi.a")

    有关CMAKE的内容需要对CMAKE有一定了解,请自行查询相关资料,这里简要介绍就是进行对应赋值,类似于常规编程语言的map,set命令左边为key,右边为value,供之后cmake实际调用准备数据,

    接下来,切换到build/src目录,设置系统变量,从注释可以看出主要是设置job,内存,硬盘可用空间等:

    echo "${COLOR_CYAN}====================================================================================="
    echo "======================= ${COLOR_WHITE}Starting EOSIO Dependency Install${COLOR_CYAN} ===========================${COLOR_NC}"
    execute cd $SRC_DIR
    set_system_vars # JOBS, Memory, disk space available, etc

    核心在set_system_vars,源码如下

     1 function set_system_vars() {
     2     if [[ $ARCH == "Darwin" ]]; then
     3         export OS_VER=$(sw_vers -productVersion)
     4         export OS_MAJ=$(echo "${OS_VER}" | cut -d'.' -f1)
     5         export OS_MIN=$(echo "${OS_VER}" | cut -d'.' -f2)
     6         export OS_PATCH=$(echo "${OS_VER}" | cut -d'.' -f3)
     7         export MEM_GIG=$(bc <<< "($(sysctl -in hw.memsize) / 1024000000)")
     8         export DISK_INSTALL=$(df -h . | tail -1 | tr -s ' ' | cut -d  -f1 || cut -d' ' -f1)
     9         export blksize=$(df . | head -1 | awk '{print $2}' | cut -d- -f1)
    10         export gbfactor=$(( 1073741824 / blksize ))
    11         export total_blks=$(df . | tail -1 | awk '{print $2}')
    12         export avail_blks=$(df . | tail -1 | awk '{print $4}')
    13         export DISK_TOTAL=$((total_blks / gbfactor ))
    14         export DISK_AVAIL=$((avail_blks / gbfactor ))
    15     else
    16         export DISK_INSTALL=$( df -h . | tail -1 | tr -s ' ' | cut -d  -f1 )
    17         export DISK_TOTAL_KB=$( df . | tail -1 | awk '{print $2}' )
    18         export DISK_AVAIL_KB=$( df . | tail -1 | awk '{print $4}' )
    19         export MEM_GIG=$(( ( ( $(cat /proc/meminfo | grep MemTotal | awk '{print $2}') / 1000 ) / 1000 ) ))
    20         export DISK_TOTAL=$(( DISK_TOTAL_KB / 1048576 ))
    21         export DISK_AVAIL=$(( DISK_AVAIL_KB / 1048576 ))
    22     fi
    23     export JOBS=${JOBS:-$(( MEM_GIG > CPU_CORES ? CPU_CORES : MEM_GIG ))}
    24 }

    因为一般是linux系统,所以重点在16到21,以及23行,分别为

    
    
    #硬盘安装地址,centos在/dev/mapper/centos-root,ubuntu在/dev/vda1
    export DISK_INSTALL=$( df -h . | tail -1 | tr -s ' ' | cut -d -f1 )
    #硬盘总空间(KB)
    export DISK_TOTAL_KB=$( df . | tail -1 | awk '{print $2}' )
    #硬盘可用空间(KB)
    export DISK_AVAIL_KB=$( df . | tail -1 | awk '{print $4}' )
    #总内存(G)
    export MEM_GIG=$(( ( ( $(cat /proc/meminfo | grep MemTotal | awk '{print $2}') / 1000 ) / 1000 ) ))
    #磁盘空间(GB)
    export DISK_TOTAL=$(( DISK_TOTAL_KB / 1048576 ))
    #可用磁盘空间(GB)
    export DISK_AVAIL=$(( DISK_AVAIL_KB / 1048576 ))
    #可用工作线程,其中CPU_CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
    export JOBS=${JOBS:-$(( MEM_GIG > CPU_CORES ? CPU_CORES : MEM_GIG ))}

    其实就是对操作系统性能进行评估,可以make并发几个线程

    接下来的代码,执行对应操作系统的build

    echo "Architecture: ${ARCH}"
    . $FILE # Execute OS specific build file

    之后就是设置cmake变量

    echo ""
    echo "${COLOR_CYAN}========================================================================"
    echo "======================= ${COLOR_WHITE}Starting EOSIO Build${COLOR_CYAN} ===========================${COLOR_NC}"
    if $VERBOSE; then
       echo "CXX: $CXX"
       echo "CC: $CC"
    fi
    execute cd $BUILD_DIR
    # LOCAL_CMAKE_FLAGS
    $ENABLE_MONGO && LOCAL_CMAKE_FLAGS="-DBUILD_MONGO_DB_PLUGIN=true ${LOCAL_CMAKE_FLAGS}" # Enable Mongo DB Plugin if user has enabled -m
    if $PIN_COMPILER; then
       CMAKE_PREFIX_PATHS="${CMAKE_PREFIX_PATHS};${LLVM_ROOT}"
       LOCAL_CMAKE_FLAGS="${PINNED_TOOLCHAIN} -DCMAKE_PREFIX_PATH='${CMAKE_PREFIX_PATHS}' ${LOCAL_CMAKE_FLAGS}"
    else
       LOCAL_CMAKE_FLAGS="-DCMAKE_CXX_COMPILER='${CXX}' -DCMAKE_C_COMPILER='${CC}' -DCMAKE_PREFIX_PATH='${CMAKE_PREFIX_PATHS}' ${LOCAL_CMAKE_FLAGS}"
    fi
    $ENABLE_DOXYGEN && LOCAL_CMAKE_FLAGS="-DBUILD_DOXYGEN='${DOXYGEN}' ${LOCAL_CMAKE_FLAGS}"
    $ENABLE_COVERAGE_TESTING && LOCAL_CMAKE_FLAGS="-DENABLE_COVERAGE_TESTING='${ENABLE_COVERAGE_TESTING}' ${LOCAL_CMAKE_FLAGS}"

    上述比较复杂,主要是构建build所需的变量,后面是实际的build过程,CMAKE需要对CMAKE有相应的了解,请自行查阅资料

    execute bash -c "$CMAKE -DCMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}' -DCORE_SYMBOL_NAME='${CORE_SYMBOL_NAME}' -DOPENSSL_ROOT_DIR='${OPENSSL_ROOT_DIR}' -DCMAKE_INSTALL_PREFIX='${EOSIO_INSTALL_DIR}' ${LOCAL_CMAKE_FLAGS} '${REPO_ROOT}'"
    execute make -j$JOBS
    execute cd $REPO_ROOT 1>/dev/null

    最后是打印build结果

    TIME_END=$(( $(date -u +%s) - $TIME_BEGIN ))
    
    echo " _______  _______  _______ _________ _______"
    echo "(  ____ (  ___  )(  ____   __   __ (  ___  )"
    echo "| (    /| (   ) || (    /   ) (   | (   ) |"
    echo "| (__    | |   | || (_____    | |   | |   | |"
    echo "|  __)   | |   | |(_____  )   | |   | |   | |"
    echo "| (      | |   | |      ) |   | |   | |   | |"
    echo "| (____/| (___) |/\____) |___) (___| (___) |"
    echo "(_______/(_______)\_______)\_______/(_______)"
    echo "=============================================${COLOR_NC}"
    
    echo "${COLOR_GREEN}EOSIO has been successfully built. $(($TIME_END/3600)):$(($TIME_END%3600/60)):$(($TIME_END%60))"
    echo "${COLOR_GREEN}You can now install using: ${SCRIPT_DIR}/eosio_install.sh${COLOR_NC}"
    echo "${COLOR_YELLOW}Uninstall with: ${SCRIPT_DIR}/eosio_uninstall.sh${COLOR_NC}"
    
    echo ""
    echo "${COLOR_CYAN}If you wish to perform tests to ensure functional code:${COLOR_NC}"
    if $ENABLE_MONGO; then
       echo "${BIN_DIR}/mongod --dbpath ${MONGODB_DATA_DIR} -f ${MONGODB_CONF} --logpath ${MONGODB_LOG_DIR}/mongod.log &"
       PATH_TO_USE=" PATH=$PATH:$OPT_DIR/mongodb/bin"
    fi
    echo "cd ${BUILD_DIR} && ${PATH_TO_USE} make test" # PATH is set as currently 'mongo' binary is required for the mongodb test
    
    echo ""
    resources

    其中resources代码在eosio.sh中,是实现打印资源地址。代码如下

    function resources() {
        echo "${COLOR_CYAN}EOSIO website:${COLOR_NC} https://eos.io"
        echo "${COLOR_CYAN}EOSIO Telegram channel:${COLOR_NC} ...(由于含有违规内容,故没有贴出来)"
        echo "${COLOR_CYAN}EOSIO resources:${COLOR_NC} https://eos.io/resources/"
        echo "${COLOR_CYAN}EOSIO Stack Exchange:${COLOR_NC} https://eosio.stackexchange.com"
    }

    整个eosio整体build过程就分析完了,接下来会重点介绍下eosio_build_centos.sh的执行过程。 

  • 相关阅读:
    (转载)VS2010/MFC编程入门之十九(对话框:颜色对话框)
    (转载)VS2010/MFC编程入门之十八(对话框:字体对话框)
    (转载)VS2010/MFC编程入门之十七(对话框:文件对话框)
    (转载)VS2010/MFC编程入门之十六(对话框:消息对话框)
    VS2010/MFC编程入门之十四(对话框:向导对话框的创建及显示)
    (转载)VS2010/MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
    (转载)VS2010/MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
    Android笔记之AsyncTask
    Android笔记之线程使用
    Android笔记之活动指示器使用
  • 原文地址:https://www.cnblogs.com/wangzxblog/p/11838522.html
Copyright © 2020-2023  润新知