i.MX Yocto项目配置脚本解析(imx-setup-release.sh)

在使用i.MX官方提供Yocto工程构建Linux系统时,通常情况下我们要先执行imx-setup-release.sh脚本进行配置操作,然后再执行bitbake target命令去构建我们想要的目标。因此,如果想要深入理解Yocto工程的运行和构建的具体的技术细节,我们还是需要以这个配置脚本为切入点,详细分析一下执行imx-setup-release.sh脚本时完成了哪些工作。

1、概述

由于imx-setup-release.sh脚本里的内容比较复杂,在它内部还嵌套了其它脚本的调用。所有,在进行详细分析之前,我在这里先告诉大家它大概做了哪些操作,以及它调用的各个脚本实现的功能。这样抱着目的来看后面的内容,反而更方便大家去理解。

总的来说,执行imx-setup-release.sh脚本完成的工作主要包含两个部分。首先,它创建了构建目录并设置了该目录下的conf目录里的内容(bitbake工具构建目标时,首先解析的就是该目录里的文件),其次它把构建用到的脚本和工具集所在的目录添加到PATH环境变量,以便于我们可以直接在终端中使用该工具集(比如我们执行bitbake target时,不需要加上bitbake所在路径)

接着再来看下内部脚本的调用关系和各个脚本实现的功能吧!

 图1.1 imx-setup-release.sh脚本内部调用关系

imx-setup-release.sh脚本通过层层的调用,最终会调用到了oe-init-build-env脚本和oe-setup-builddir脚本,这两个脚本是在poky里面实现的。所谓poky是BitBake工具集和OE组件组合在一起以形成参考构建主机,Yocto项目的构建主机是基于这个来做的,可以理解为Yocto项目继承了OpenEmbedded(OE)项目并且丰富了一些内容。所以,Yocto项目中最底层还是会调用到OE构建环境的脚本,但调用OE里的这些脚本之后,它还会根据自己的需求在自己构建的脚本中对OE构建环境默认的配置进行了适当的修改,这些修改的内容就是在imx-setup-release.sh和setup-environmen脚本中实现的。

下面简要的说下前面列出的各个脚本的实现的功能:

  • oe-buildenv-internal:检测目标主机上Python版本(bitbake等构建工具是Python编写的,运行时需要Python来解析),将构建用的bitbake等工具路径临时添加到PATH环境变量,设置构建工具集用到的环境变量
  • oe-setup-builddir:创建构建目录,将poky目录下meta-poky层的conf目录下默认的配置文件拷贝到构建目录的conf目录中去
  • oe-init-build-env:OE中提供给用户用来进行配置构建环境的脚本,即它内部调用oe-buildenv-internal和oe-setup-builddir脚本
  • setup-environment:Yocto项目中提供给用户用来进行配置构建环境的脚本,调用oe-init-build-env设置默认配置,然后再根据自己需求做了一些修改
  • imx-setup-release.sh:NXP公司维护Yocto版本提供给用户用来配置构建环境的脚本,调用setup-envitonment设置默认配置,然后再根据基础上做了一些修改

2、构建脚本分析

前面对Yocto项目的构建环境的脚本间的调用关系和每个脚本所实现的功能做了简单的介绍,想必大家对配置过程有了一个大概的认识,现在就开始脚本源码的角度详细的分析每个脚本所做的具体工作。有了前面的内容作为铺垫,再来看下面的这些内容应该容易理解了些。

2.1 oe-buildenv-internal

#!/bin/sh

# OE-Core Build Environment Setup Script
#
# Copyright (C) 2006-2011 Linux Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

if ! $(return >/dev/null 2>&1) ; then
    echo 'oe-buildenv-internal: error: this script must be sourced'
    echo ''
    echo 'Usage: . $OEROOT/scripts/oe-buildenv-internal &&'
    echo ''
    echo 'OpenEmbedded oe-buildenv-internal - an internal script that is'
    echo 'used in oe-init-build-env to initialize oe build environment'
    echo ''
    exit 2
fi

# It is assumed OEROOT is already defined when this is called
if [ -z "$OEROOT" ]; then--------------------------------------------->echo >&2 "Error: OEROOT is not defined!"
    return 1
fi

if [ -z "$OE_SKIP_SDK_CHECK" ] && [ -n "$OECORE_SDK_VERSION" ]; then
    echo >&2 "Error: The OE SDK/ADT was detected as already being present in this shell environment. Please use a clean shell when sourcing this environment script."
    return 1
fi

py_v27_check=$(python2 -c 'import sys; print sys.version_info >= (2,7,3)')--------------------------------------------->if [ "$py_v27_check" != "True" ]; then
    echo >&2 "OpenEmbedded requires 'python' to be python v2 (>= 2.7.3), not python v3."
    echo >&2 "Please upgrade your python v2."
fi
unset py_v27_check

# We potentially have code that doesn't parse correctly with older versions 
# of Python, and rather than fixing that and being eternally vigilant for 
# any other new feature use, just check the version here.
py_v34_check=$(python3 -c 'import sys; print(sys.version_info >= (3,4,0))')
if [ "$py_v34_check" != "True" ]; then
    echo >&2 "BitBake requires Python 3.4.0 or later as 'python3'"
    return 1
fi
unset py_v34_check

if [ -z "$BDIR" ]; then--------------------------------------------->if [ -z "$1" ]; then
        BDIR="build"
    else
        BDIR="$1"
        if [ "$BDIR" = "/" ]; then
            echo >&2 "Error: / is not supported as a build directory."
            return 1
        fi

        # Remove any possible trailing slashes. This is used to work around
        # buggy readlink in Ubuntu 10.04 that doesn't ignore trailing slashes
        # and hence "readlink -f new_dir_to_be_created/" returns empty.
        BDIR=$(echo $BDIR | sed -re 's|/+$||')

        BDIR=$(readlink -f "$BDIR")
        if [ -z "$BDIR" ]; then
            PARENTDIR=$(dirname "$1")
            echo >&2 "Error: the directory $PARENTDIR does not exist?"
            return 1
        fi
    fi
    if [ -n "$2" ]; then
        BITBAKEDIR="$2"
    fi
fi
if [ "${BDIR#/}" != "$BDIR" ]; then
    BUILDDIR="$BDIR"
else
    BUILDDIR="$(pwd)/$BDIR"
fi
unset BDIR

if [ -z "$BITBAKEDIR" ]; then--------------------------------------------->④
    BITBAKEDIR="$OEROOT/bitbake$BBEXTRA"
    test -d "$BITBAKEDIR" || BITBAKEDIR="$OEROOT/../bitbake$BBEXTRA"
fi

BITBAKEDIR=$(readlink -f "$BITBAKEDIR")
BUILDDIR=$(readlink -f "$BUILDDIR")
BBPATH=$BUILDDIR

export BBPATH

if [ ! -d "$BITBAKEDIR" ]; then
    echo >&2 "Error: The bitbake directory ($BITBAKEDIR) does not exist!  Please ensure a copy of bitbake exists at this location or specify an alternative path on the command line"
    return 1
fi

# Make sure our paths are at the beginning of $PATH
for newpath in "$BITBAKEDIR/bin" "$OEROOT/scripts"; do--------------------------------------------->⑤
    # Remove any existences of $newpath from $PATH
    PATH=$(echo $PATH | sed -re "s#(^|:)$newpath(:|$)#\2#g;s#^:##")

    # Add $newpath to $PATH
    PATH="$newpath:$PATH"
done
unset BITBAKEDIR newpath

# Used by the runqemu script
export BUILDDIR--------------------------------------------->⑤
export PATH

BB_ENV_EXTRAWHITE_OE="MACHINE DISTRO TCMODE TCLIBC HTTP_PROXY http_proxy \
HTTPS_PROXY https_proxy FTP_PROXY ftp_proxy FTPS_PROXY ftps_proxy ALL_PROXY \
all_proxy NO_PROXY no_proxy SSH_AGENT_PID SSH_AUTH_SOCK BB_SRCREV_POLICY \
SDKMACHINE BB_NUMBER_THREADS BB_NO_NETWORK PARALLEL_MAKE GIT_PROXY_COMMAND \
SOCKS5_PASSWD SOCKS5_USER SCREENDIR STAMPS_DIR BBPATH_EXTRA BB_SETSCENE_ENFORCE"

BB_ENV_EXTRAWHITE="$(echo $BB_ENV_EXTRAWHITE $BB_ENV_EXTRAWHITE_OE | tr ' ' '\n' | LC_ALL=C sort --unique | tr '\n' ' ')"

export BB_ENV_EXTRAWHITE
oe-buildenv-internal

① 检测OEROOT变量是否定义,如果没定义脚本立刻返回。OEROOT变量在oe-init-build-env脚本中设置,该变量表示oe-init-build-env脚本所在目录位置信息

② 检测主机安装python版本信息,Python2需大于2.7.3,Python3需大于3.4.0

③ 设置BUILDDIR变量等于构建目录的绝对路径信息。如果执行该脚本时没指定构建目录的路径为脚本的第一个参数的话,脚本设置使用"build"作为默认构建目录名

④ 令BITBAKEDIR="$OEROOT/bitbake,该路径是存放bitbake工具集和脚本的路径

⑤ 将"$BITBAKEDIR/bin" "$OEROOT/scripts"路径临时增加到PATH环境变量中,$BITBAKEDIR/bin路径存放的是bitbake工具,$OEROOT/scripts目录存放的是构建的脚本

⑥ 设置构建工具集使用的环境变量

2.2 oe-buildenv-builddir

#!/bin/sh

# OE Build Environment Setup Script
#
# Copyright (C) 2006-2011 Linux Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

if [ -z "$BUILDDIR" ]; then
    echo >&2 "Error: The build directory (BUILDDIR) must be set!"
    exit 1
fi

if [ "$1" = '--help' -o "$1" = '-h' ]; then
    echo 'Usage: oe-setup-builddir'
    echo ''
    echo "OpenEmbedded setup-builddir - setup build directory $BUILDDIR"
    echo ''
    exit 2
fi

mkdir -p "$BUILDDIR/conf"--------------------------------------------------->if [ ! -d "$BUILDDIR" ]; then
    echo >&2 "Error: The builddir ($BUILDDIR) does not exist!"
    exit 1
fi

if [ ! -w "$BUILDDIR" ]; then
    echo >&2 "Error: Cannot write to $BUILDDIR, perhaps try sourcing with a writable path? i.e. . oe-init-build-env ~/my-build"
    exit 1
fi

# Attempting removal of sticky,setuid bits from BUILDDIR, BUILDDIR/conf
chmod -st "$BUILDDIR" 2>/dev/null || echo "WARNING: unable to chmod $BUILDDIR"
chmod -st "$BUILDDIR/conf" 2>/dev/null || echo "WARNING: unable to chmod $BUILDDIR/conf"

cd "$BUILDDIR"------------------------------------------------>if [ -f "$BUILDDIR/conf/templateconf.cfg" ]; then-------------------------------------->③
    TEMPLATECONF=$(cat "$BUILDDIR/conf/templateconf.cfg")
fi

. $OEROOT/.templateconf---------------------------------------------------------------->if [ ! -f "$BUILDDIR/conf/templateconf.cfg" ]; then------------------------------------>echo "$TEMPLATECONF" >"$BUILDDIR/conf/templateconf.cfg"
fi

# 
# $TEMPLATECONF can point to a directory for the template local.conf & bblayers.conf
#
if [ -n "$TEMPLATECONF" ]; then------------------------------------------------------->if [ ! -d "$TEMPLATECONF" ]; then
        # Allow TEMPLATECONF=meta-xyz/conf as a shortcut
        if [ -d "$OEROOT/$TEMPLATECONF" ]; then
            TEMPLATECONF="$OEROOT/$TEMPLATECONF"
        fi
        if [ ! -d "$TEMPLATECONF" ]; then
            echo >&2 "Error: TEMPLATECONF value points to nonexistent directory '$TEMPLATECONF'"
            exit 1
        fi
    fi
    OECORELAYERCONF="$TEMPLATECONF/bblayers.conf.sample"
    OECORELOCALCONF="$TEMPLATECONF/local.conf.sample"
    OECORENOTESCONF="$TEMPLATECONF/conf-notes.txt"
fi

unset SHOWYPDOC
if [ -z "$OECORELOCALCONF" ]; then------------------------------------------------------->⑦
    OECORELOCALCONF="$OEROOT/meta/conf/local.conf.sample"
fi
if [ ! -r "$BUILDDIR/conf/local.conf" ]; then------------------------------------------------------->cat <<EOM
You had no conf/local.conf file. This configuration file has therefore been
created for you with some default values. You may wish to edit it to, for
example, select a different MACHINE (target hardware). See conf/local.conf
for more information as common configuration options are commented.

EOM
    cp -f $OECORELOCALCONF "$BUILDDIR/conf/local.conf"
    SHOWYPDOC=yes
fi

if [ -z "$OECORELAYERCONF" ]; then------------------------------------------------------->⑦
    OECORELAYERCONF="$OEROOT/meta/conf/bblayers.conf.sample"
fi
if [ ! -r "$BUILDDIR/conf/bblayers.conf" ]; then------------------------------------------------------->cat <<EOM
You had no conf/bblayers.conf file. This configuration file has therefore been
created for you with some default values. To add additional metadata layers
into your configuration please add entries to conf/bblayers.conf.

EOM

    # Put the abosolute path to the layers in bblayers.conf so we can run
    # bitbake without the init script after the first run
    # ##COREBASE## is deprecated as it's meaning was inconsistent, but continue
    # to replace it for compatibility.
    sed -e "s|##OEROOT##|$OEROOT|g" \
        -e "s|##COREBASE##|$OEROOT|g" \
        $OECORELAYERCONF > "$BUILDDIR/conf/bblayers.conf"
    SHOWYPDOC=yes
fi

# Prevent disturbing a new GIT clone in same console
unset OECORELOCALCONF
unset OECORELAYERCONF

# Ending the first-time run message. Show the YP Documentation banner.
if [ ! -z "$SHOWYPDOC" ]; then--------------------------------------------------->cat <<EOM
The Yocto Project has extensive documentation about OE including a reference
manual which can be found at:
    http://yoctoproject.org/documentation

For more information about OpenEmbedded see their website:
    http://www.openembedded.org/

EOM
#    unset SHOWYPDOC
fi

if [ -z "$OECORENOTESCONF" ]; then----------------------------------------------->⑦
    OECORENOTESCONF="$OEROOT/meta/conf/conf-notes.txt"
fi
[ ! -r "$OECORENOTESCONF" ] || cat $OECORENOTESCONF------------------------------->⑩
unset OECORENOTESCONF
oe-buildenv-builddir

① 递归创建$BUILDDIR/conf,$BUILDDIR表示的是构建目录的路径,创建的目录和子目录应该有可读可写权限(此时创建了构建目录,并且在构建目录下创建了conf目录)

② 切换到构建目录

③ 判断构建目录下子目录conf中templateconf.cfg文件是否存在,如果存在用它里面的内容去设置TEMPLATECONF变量(如果是第一次创建肯定不存在此文件,此时使用$OEROOT/.templateconf中对TEMPLATECONF变量设置)

④ $OEROOT/.templateconf脚本内容:TEMPLATECONF=${TEMPLATECONF:-meta-poky/conf}。如果是第一次构建,构建目录下子目录conf中templateconf.cfg文件不存在,在前面TEMPLATECONF变量没被设置,此处设置TEMPLATECONF=meta-poky/conf

⑤ 如果是第一次构建,需要将meta-poky/conf信息写到$BUILDDIR/conf/templateconf.cfg文件中

⑥ TEMPLATECONF="$OEROOT/meta-poky/conf"
     OECORELAYERCONF="$OEROOT/meta-poky/conf/bblayers.conf.sample"
     OECORELOCALCONF="$OEROOT/meta-poky/conf/local.conf.sample"
     OECORENOTESCONF="$OEROOT/meta-poky/conf/conf-notes.txt"
    (OEROOT=$(pwd)/sources/poky,此处的$(pwd)表示你yocto工程存放的绝对路径)

使用poky/meta-poky/conf目录下的bblayers.conf.sample和local.conf.sample作为默认配置文件

⑦ 判断poky/meta-poky/conf目录下的bblayers.conf.sample和local.conf.sample配置文件是否存在,不存在使用poky/meta/conf目录下的

⑧ 如果是第一次构建,构建目录下conf中bblayers.conf、local.conf文件不存在
拷贝$OEROOT/meta-poky/conf/bblayers.conf.sample到$BUILDDIR/conf/bblayers.conf文件
拷贝$OEROOT/meta-poky/conf/local.conf.sample到$BUILDDIR/conf/local.conf文件

(在拷贝OEROOT/meta-poky/conf/local.conf.sample文件时,将文件中含有"##OEROOT##"和"##COREBASE##"内容换成$OEROOT表示的路径后,再拷贝到$BUILDDIR/conf/local.conf文件)

这里的$BUILDDIR表示的是构建目录的位置信息

⑨ 如果时第一次构建,SHOWYPDOC=yes,打印下面信息

The Yocto Project has extensive documentation about OE including a reference
                    manual which can be found at:
                        http://yoctoproject.org/documentation
                    
                    For more information about OpenEmbedded see their website:
                        http://www.openembedded.org/

⑩ 如果是第一次构建,打印$OEROOT/meta-poky/conf/conf-notes.txt文件信息

2.3 oe-init-build-env

#!/bin/sh

# OE Build Environment Setup Script
#
# Copyright (C) 2006-2011 Linux Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

#
# Normally this is called as '. ./oe-init-build-env <builddir>'
#
# This works in most shells (not dash), but not all of them pass the arguments
# when being sourced.  To workaround the shell limitation use "set <builddir>"
# prior to sourcing this script.
#
if [ -n "$BASH_SOURCE" ]; then-------------------------->①
    THIS_SCRIPT=$BASH_SOURCE
elif [ -n "$ZSH_NAME" ]; then
    THIS_SCRIPT=$0
else
    THIS_SCRIPT="$(pwd)/oe-init-build-env"
    if [ ! -e "$THIS_SCRIPT" ]; then
        echo "Error: $THIS_SCRIPT doesn't exist!" >&2
        echo "Please run this script in oe-init-build-env's directory." >&2
        exit 1
    fi
fi
if [ -n "$BBSERVER" ]; then
    unset BBSERVER
fi

if [ -z "$ZSH_NAME" ] && [ "$0" = "$THIS_SCRIPT" ]; then
    echo "Error: This script needs to be sourced. Please run as '. $THIS_SCRIPT'" >&2
    exit 1
fi

if [ -z "$OEROOT" ]; then--------------------------------->②
    OEROOT=$(dirname "$THIS_SCRIPT")
    OEROOT=$(readlink -f "$OEROOT")
fi
unset THIS_SCRIPT

export OEROOT-------------------------------------------->③
. $OEROOT/scripts/oe-buildenv-internal &&
    TEMPLATECONF="$TEMPLATECONF" $OEROOT/scripts/oe-setup-builddir || {---------------->④
    unset OEROOT
    return 1
}
unset OEROOT

[ -z "$BUILDDIR" ] || cd "$BUILDDIR"-------------------------------------------------->⑤
oe-init-build-env

① 判断是哪种shell解析的oe-init-build-env,并根据该shell解释器的特点,获取该脚本所在的位置信息,位置信息存放到THIS_SCRIPT变量中

. 或者source这种执行脚本的方式,会使用主机默认的shell解释器解释脚本。如果是以./xxx方式运行脚本,使用的是脚本开头指定的解释器,如果脚本开头没指定使用主机默认的解释器

② 判断是否设置了OEROOT变量,如果OEROOT没被设置,提取THIS_SCRIPT的前缀去设置OEROOT

(由于在调用该脚本前,setup-environment脚本设置OEROOT=$PWD/sources/poky,所以此处不会被执行)

③ export OEROOT 设置临时环境变量

④ 执行$PWD/sources/poky目录下的子目录scripts中的oe-buildenv-internal和oe-setup-builddir脚本

⑤ 判断oe-buildenv-internal和oe-setup-builddir脚本中是否设置了BUILDDIR变量,如果设置了,切换到他表示的目录里

2.4 setup-environment

#!/bin/sh
# -*- mode: shell-script; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#
# Copyright (C) 2012, 2013, 2016 O.S. Systems Software LTDA.
# Authored-by:  Otavio Salvador <otavio@ossystems.com.br>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Add options for the script
# Copyright (C) 2013 Freescale Semiconductor, Inc.

CWD=`pwd`
PROGNAME="setup-environment"
PACKAGE_CLASSES=${PACKAGE_CLASSES:-package_rpm}

usage()
{
    echo -e "
Usage: MACHINE=<machine> DISTRO=<distro> source $PROGNAME <build-dir>
Usage:                                   source $PROGNAME <build-dir>
    <machine>    machine name
    <distro>     distro name
    <build-dir>  build directory

The first usage is for creating a new build directory. In this case, the
script creates the build directory <build-dir>, configures it for the
specified <machine> and <distro>, and prepares the calling shell for running
bitbake on the build directory.

The second usage is for using an existing build directory. In this case,
the script prepares the calling shell for running bitbake on the build
directory <build-dir>. The build directory configuration is unchanged.
"

    ls sources/*/conf/machine/*.conf > /dev/null 2>&1
    ls sources/meta-freescale-distro/conf/distro/fslc-*.conf > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo -e "
Supported machines: `echo; ls sources/*/conf/machine/*.conf \
| sed s/\.conf//g | sed -r 's/^.+\///' | xargs -I% echo -e "\t%"`

Supported Freescale's distros: `echo; ls sources/meta-freescale-distro/conf/distro/fslc-*.conf \
| sed s/\.conf//g | sed -r 's/^.+\///' | xargs -I% echo -e "\t%"`

Available Poky's distros: `echo; ls sources/poky/meta-poky/conf/distro/*.conf \
| sed s/\.conf//g | sed -r 's/^.+\///' | xargs -I% echo -e "\t%"`

Examples:

- To create a new Yocto build directory:
  $ MACHINE=imx6qdlsabresd DISTRO=fslc-framebuffer source $PROGNAME build

- To use an existing Yocto build directory:
  $ source $PROGNAME build
"
    fi
}

clean_up()
{
   unset EULA LIST_MACHINES VALID_MACHINE
   unset CWD TEMPLATES SHORTOPTS LONGOPTS ARGS PROGNAME
   unset generated_config updated
   unset MACHINE SDKMACHINE DISTRO OEROOT
}

# get command line options
SHORTOPTS="h"
LONGOPTS="help"

ARGS=$(getopt --options $SHORTOPTS  \
  --longoptions $LONGOPTS --name $PROGNAME -- "$@" )
# Print the usage menu if invalid options are specified
if [ $? != 0 -o $# -lt 1 ]; then
   usage && clean_up
   return 1
fi

eval set -- "$ARGS"--------------------------------------->①
while true;
do
    case $1 in
        -h|--help)
           usage
           clean_up
           return 0
           ;;
        --)
           shift
           break
           ;;
    esac
done

if [ "$(whoami)" = "root" ]; then-------------------------------->②
    echo "ERROR: do not use the BSP as root. Exiting..."
fi

if [ ! -e $1/conf/local.conf.sample ]; then---------------------->③
    build_dir_setup_enabled="true"
else
    build_dir_setup_enabled="false"
fi

if [ "$build_dir_setup_enabled" = "true" ] && [ -z "$MACHINE" ]; then
    usage
    echo -e "ERROR: You must set MACHINE when creating a new build directory."
    clean_up
    return 1
fi

if [ -z "$SDKMACHINE" ]; then
    SDKMACHINE='i686'
fi

if [ "$build_dir_setup_enabled" = "true" ] && [ -z "$DISTRO" ]; then
    usage
    echo -e "ERROR: You must set DISTRO when creating a new build directory."
    clean_up
    return 1
fi

[ -z "$FSL_EULA_FILE" ] && FSL_EULA_FILE=$CWD/sources/meta-freescale/EULA--------------->④
if [ ! -e $FSL_EULA_FILE ]; then
    echo -e "ERROR: EULA not found at $FSL_EULA_FILE."
    clean_up
    return 1
fi

OEROOT=$PWD/sources/poky---------------------------------->⑤
if [ -e $PWD/sources/oe-core ]; then
    OEROOT=$PWD/sources/oe-core
fi

. $OEROOT/oe-init-build-env $CWD/$1 > /dev/null----------------------->⑥

# if conf/local.conf not generated, no need to go further
if [ ! -e conf/local.conf ]; then
    clean_up && return 1
fi

# Clean up PATH, because if it includes tokens to current directories somehow,
# wrong binaries can be used instead of the expected ones during task execution
export PATH="`echo $PATH | sed 's/\(:.\|:\)*:/:/g;s/^.\?://;s/:.\?$//'`"----------------------->⑦

generated_config=
if [ "$build_dir_setup_enabled" = "true" ]; then-------------------------->⑧
    mv conf/local.conf conf/local.conf.sample

    # Generate the local.conf based on the Yocto defaults
    TEMPLATES=$CWD/sources/base/conf 
    grep -v '^#\|^$' conf/local.conf.sample > conf/local.conf
    cat >> conf/local.conf <<EOF

DL_DIR ?= "\${BSPDIR}/downloads/"
EOF
    # Change settings according environment
    sed -e "s,MACHINE ??=.*,MACHINE ??= '$MACHINE',g" \
        -e "s,SDKMACHINE ??=.*,SDKMACHINE ??= '$SDKMACHINE',g" \
        -e "s,DISTRO ?=.*,DISTRO ?= '$DISTRO',g" \
        -e "s,PACKAGE_CLASSES ?=.*,PACKAGE_CLASSES ?= '$PACKAGE_CLASSES',g" \
        -i conf/local.conf

    cp $TEMPLATES/* conf/

    for s in $HOME/.oe $HOME/.yocto; do
        if [ -e $s/site.conf ]; then
            echo "Linking $s/site.conf to conf/site.conf"
            ln -s $s/site.conf conf
        fi
    done

    generated_config=1
fi

# Handle EULA setting
EULA_ACCEPTED=

# EULA has been accepted already (ACCEPT_FSL_EULA is set in local.conf)
if grep -q '^\s*ACCEPT_FSL_EULA\s*=\s*["'\'']..*["'\'']' conf/local.conf; then--------------------------->⑨
    EULA_ACCEPTED=1
fi

if [ -z "$EULA_ACCEPTED" ] && [ -n "$EULA" ]; then
    # The FSL EULA is not set as accepted in local.conf, but the EULA
    # variable is set in the environment, so we just configure
    # ACCEPT_FSL_EULA in local.conf according to $EULA.
    echo "ACCEPT_FSL_EULA = \"$EULA\"" >> conf/local.conf
elif [ -n "$EULA_ACCEPTED" ]; then
    # The FSL EULA has been accepted once, so ACCEPT_FSL_EULA is set
    # in local.conf.  No need to do anything.
    :
else
    # THE FSL EULA is not set as accepted in local.conf, and EULA is
    # not set in the environment, so we need to ask user if he/she
    # accepts the FSL EULA:
    cat <<EOF

Some BSPs depend on libraries and packages which are covered by Freescale's
End User License Agreement (EULA). To have the right to use these binaries in
your images, you need to read and accept the following...

EOF

    sleep 4

    more -d $FSL_EULA_FILE
    echo
    REPLY=
    while [ -z "$REPLY" ]; do
        echo -n "Do you accept the EULA you just read? (y/n) "
        read REPLY
        case "$REPLY" in
            y|Y)
            echo "EULA has been accepted."
            echo "ACCEPT_FSL_EULA = \"1\"" >> conf/local.conf
            ;;
            n|N)
            echo "EULA has not been accepted."
            ;;
            *)
            REPLY=
            ;;
        esac
    done
fi

cat <<EOF

Welcome to Freescale Community BSP

The Yocto Project has extensive documentation about OE including a
reference manual which can be found at:
    http://yoctoproject.org/documentation

For more information about OpenEmbedded see their website:
    http://www.openembedded.org/

You can now run 'bitbake <target>'

Common targets are:
    core-image-minimal
    meta-toolchain
    meta-toolchain-sdk
    adt-installer
    meta-ide-support

EOF

if [ -n "$generated_config" ]; then------------------->⑩
    cat <<EOF
Your build environment has been configured with:

    MACHINE=$MACHINE
    SDKMACHINE=$SDKMACHINE
    DISTRO=$DISTRO
    EULA=$EULA
EOF
else
    echo "Your configuration files at $1 have not been touched."
fi

clean_up
setup-environment

① 命令行参数处理,如果执行脚本传入的是-h|--help参数,打印帮助信息,退出脚本

(有关脚本如何处理命令行信息,可以参考这里

② 判断是否是root用户执行脚本,如果是,打印错误信息并退出

③ 根据构建目录下的conf/local.conf.sample文件是否存在,判断是否为第一次构建。如果是第一次构建build_dir_setup_enabled="true",否则build_dir_setup_enabled="false"

如果是第一次构建,但在执行脚本时没设置MACHINE和DISTRO变量,打印错误提示信息,并退出脚本

④ 判断是否设置了FSL_EULA_FILE变量(该变量表示最终用户协议文件),如果没设置,设置FSL_EULA_FILE=$(pwd)/sources/meta-freescale/EULA

(前面imx-setup-release.sh脚本已经设置了FSL_EULA_FILE变量,FSL_EULA_FILE=$(pwd)/sources/meta-imx/EULA.txt)   

⑤ 判断$PWD/sources/oe-core该目录是否存在,如果存在,OEROOT=$PWD/sources/oe-core,否则,OEROOT=$PWD/sources/poky

(此处OEROOT=$PWD/sources/poky)

⑥ $OEROOT/oe-init-build-env $CWD/$1 > /dev/null
  执行$PWD/sources/poky目录下的oe-init-build-env脚本,执行该脚本传入的参数是构建目录的绝对路径,脚本的输出信息重定向到/dev/null(即oe-init-build-env脚本打印的内容不显示到终端)

⑦ 重新设置PATH环境变量
        export PATH="`echo $PATH | sed 's/\(:.\|:\)*:/:/g;s/^.\?://;s/:.\?$//'`"

⑧ 如果是第一次执行配置:build_dir_setup_enabled" = "true"
        将构建目录下conf目录里的local.conf重新修改名字为local.conf.sample
        TEMPLATES=$CWD/sources/base/conf
        将local.conf.sample文件中那些非#开头和$开头的内容写道local.conf中
        
        sed -e "s,MACHINE ??=.*,MACHINE ??= '$MACHINE',g" \
        -e "s,SDKMACHINE ??=.*,SDKMACHINE ??= '$SDKMACHINE',g" \
        -e "s,DISTRO ?=.*,DISTRO ?= '$DISTRO',g" \
        -e "s,PACKAGE_CLASSES ?=.*,PACKAGE_CLASSES ?= '$PACKAGE_CLASSES',g" \
        -i conf/local.conf

        将DL_DIR ?= "\${BSPDIR}/downloads/"插入到local.conf文件中
       
        将local.conf文件中MACHINE ??= 替换成MACHINE ??= '$MACHINE'
        DISTRO ?=.*替换成DISTRO ?= '$DISTRO'
         ...
        
        拷贝TEMPLATES描述目录下内容(该目录下只有一个bblayers.conf文件)到构建目录中的conf目录里(TEMPLATES=$CWD/sources/base/conf)

        (sources/base/conf目录下只有一个bblaers.conf文件,拷贝该目录下bblayers.conf文件到构建目录的conf目录,覆盖了oe-buildenv-internal脚本中在构建目录的conf目录设置的默认的bblayers.conf文件)
        
        generated_config=1

⑨ 判断是否是第一次构建,如果是第一次构建,打印出EULA信息,提示让用户接受。用户接受后ACCEPT_FSL_EULA=1会被追加到conf/local.conf文件中

紧接着打印下面信息
        Welcome to Freescale Community BSP

        The Yocto Project has extensive documentation about OE including a
        reference manual which can be found at:
            http://yoctoproject.org/documentation

        For more information about OpenEmbedded see their website:
            http://www.openembedded.org/

        You can now run 'bitbake <target>'

        Common targets are:
            core-image-minimal
            meta-toolchain
            meta-toolchain-sdk
            adt-installer
            meta-ide-support

⑩ 如果是第一次配置(根据generated_config判断),打印下面信息
            Your build environment has been configured with:

            MACHINE=$MACHINE
            SDKMACHINE=$SDKMACHINE
            DISTRO=$DISTRO
            EULA=$EULA

否则打印下面信息
            Your configuration files at $1 have not been touched.

2.5 imx-setup-release.sh

#!/bin/sh
#
# i.MX Yocto Project Build Environment Setup Script
#
# Copyright (C) 2011-2016 Freescale Semiconductor
# Copyright 2017 NXP
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

. sources/meta-imx/tools/setup-utils.sh

CWD=`pwd`
PROGNAME="setup-environment"
exit_message ()
{
   echo "To return to this build environment later please run:"
   echo "    source setup-environment <build_dir>"

}

usage()
{
    echo -e "\nUsage: source imx-setup-release.sh
    Optional parameters: [-b build-dir] [-h]"
echo "
    * [-b build-dir]: Build directory, if unspecified script uses 'build' as output directory
    * [-h]: help
"
}


clean_up()
{

    unset CWD BUILD_DIR FSLDISTRO
    unset fsl_setup_help fsl_setup_error fsl_setup_flag
    unset usage clean_up
    unset ARM_DIR META_FSL_BSP_RELEASE
    exit_message clean_up
}

# get command line options
OLD_OPTIND=$OPTIND
unset FSLDISTRO

while getopts "k:r:t:b:e:gh" fsl_setup_flag---------------------->(1
do
    case $fsl_setup_flag in
        b) BUILD_DIR="$OPTARG";
           echo -e "\n Build directory is " $BUILD_DIR
           ;;
        h) fsl_setup_help='true';
           ;;
        \?) fsl_setup_error='true';
           ;;
    esac
done
shift $((OPTIND-1))
if [ $# -ne 0 ]; then
    fsl_setup_error=true
    echo -e "Invalid command line ending: '$@'"
fi
OPTIND=$OLD_OPTIND
if test $fsl_setup_help; then
    usage && clean_up && return 1
elif test $fsl_setup_error; then
    clean_up && return 1
fi


if [ -z "$DISTRO" ]; then----------------------------------->(2
    if [ -z "$FSLDISTRO" ]; then
        FSLDISTRO='fsl-imx-xwayland'
    fi
else
    FSLDISTRO="$DISTRO"
fi

if [ -z "$BUILD_DIR" ]; then---------------------------------->(2
    BUILD_DIR='build'
fi

if [ -z "$MACHINE" ]; then----------------------------------->(2
    echo setting to default machine
    MACHINE='imx6qpsabresd'
fi

case $MACHINE in
imx8*)
    case $DISTRO in
    *wayland)
        : ok
        ;;
    *)
        echo -e "\n ERROR - Only Wayland distros are supported for i.MX 8 or i.MX 8M"
        echo -e "\n"
        return 1
        ;;
    esac
    ;;
*)
    : ok
    ;;
esac

# Cleanup previous meta-freescale/EULA overrides
cd $CWD/sources/meta-freescale--------------------------------------------->(3
if [ -h EULA ]; then
    echo Cleanup meta-freescale/EULA...
    git checkout -- EULA
fi
if [ ! -f classes/fsl-eula-unpack.bbclass ]; then
    echo Cleanup meta-freescale/classes/fsl-eula-unpack.bbclass...
    git checkout -- classes/fsl-eula-unpack.bbclass
fi
cd - ----------------------------------->(4

# Override the click-through in meta-freescale/EULA
FSL_EULA_FILE=$CWD/sources/meta-imx/EULA.txt---------------------->(5

# Set up the basic yocto environment
if [ -z "$DISTRO" ]; then----------------------------------------->(6
   DISTRO=$FSLDISTRO MACHINE=$MACHINE . ./$PROGNAME $BUILD_DIR
else
   MACHINE=$MACHINE . ./$PROGNAME $BUILD_DIR
fi

# Point to the current directory since the last command changed the directory to $BUILD_DIR
BUILD_DIR=.--------------------------------->(7

if [ ! -e $BUILD_DIR/conf/local.conf ]; then---------------------->(8
    echo -e "\n ERROR - No build directory is set yet. Run the 'setup-environment' script before running this script to create " $BUILD_DIR
    echo -e "\n"
    return 1
fi

# On the first script run, backup the local.conf file
# Consecutive runs, it restores the backup and changes are appended on this one.
if [ ! -e $BUILD_DIR/conf/local.conf.org ]; then------------------>(9
    cp $BUILD_DIR/conf/local.conf $BUILD_DIR/conf/local.conf.org
else
    cp $BUILD_DIR/conf/local.conf.org $BUILD_DIR/conf/local.conf
fi

echo >> conf/local.conf----------------------------------------->(10
echo "# Switch to Debian packaging and include package-management in the image" >> conf/local.conf
echo "PACKAGE_CLASSES = \"package_deb\"" >> conf/local.conf
echo "EXTRA_IMAGE_FEATURES += \"package-management\"" >> conf/local.conf

if [ ! -e $BUILD_DIR/conf/bblayers.conf.org ]; then-------------->(11
    cp $BUILD_DIR/conf/bblayers.conf $BUILD_DIR/conf/bblayers.conf.org
else
    cp $BUILD_DIR/conf/bblayers.conf.org $BUILD_DIR/conf/bblayers.conf
fi


META_FSL_BSP_RELEASE="${CWD}/sources/meta-imx/meta-bsp"--------->(12

echo "" >> $BUILD_DIR/conf/bblayers.conf
echo "# i.MX Yocto Project Release layers" >> $BUILD_DIR/conf/bblayers.conf------------------------>(13
hook_in_layer meta-imx/meta-bsp---------------------->(14
hook_in_layer meta-imx/meta-sdk
hook_in_layer meta-imx/meta-ml
hook_in_layer meta-nxp-demo-experience

echo "" >> $BUILD_DIR/conf/bblayers.conf-------------------------->(15
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-browser\"" >> $BUILD_DIR/conf/bblayers.conf
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-rust\"" >> $BUILD_DIR/conf/bblayers.conf
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-clang\"" >> $BUILD_DIR/conf/bblayers.conf
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-openembedded/meta-gnome\"" >> $BUILD_DIR/conf/bblayers.conf
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-openembedded/meta-networking\"" >> $BUILD_DIR/conf/bblayers.conf
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-openembedded/meta-filesystems\"" >> $BUILD_DIR/conf/bblayers.conf

echo "BBLAYERS += \"\${BSPDIR}/sources/meta-qt5\"" >> $BUILD_DIR/conf/bblayers.conf
echo "BBLAYERS += \"\${BSPDIR}/sources/meta-python2\"" >> $BUILD_DIR/conf/bblayers.conf

if [ -d ../sources/meta-ivi ]; then
    echo -e "\n## Genivi layers" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-gplv2\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-ivi/meta-ivi\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-ivi/meta-ivi-bsp\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-ivi/meta-ivi-test\"" >> $BUILD_DIR/conf/bblayers.conf
fi

echo BSPDIR=$BSPDIR----------------------------->(16
echo BUILD_DIR=$BUILD_DIR

# Support integrating community meta-freescale instead of meta-fsl-arm
if [ -d ../sources/meta-freescale ]; then-------------->(17
    echo meta-freescale directory found
    # Change settings according to environment
    sed -e "s,meta-fsl-arm\s,meta-freescale ,g" -i conf/bblayers.conf
    sed -e "s,\$.BSPDIR./sources/meta-fsl-arm-extra\s,,g" -i conf/bblayers.conf
fi

cd  $BUILD_DIR
clean_up
unset FSLDISTRO
imx-setup-release.sh

1) 命令行参数处理
    BUILD_DIR等于脚本-b选项后面的参数

2) 判断执行脚本时,是否设置了DISTRO变量
        如果DISTRO变量没被设置,再进一步判断FSLDISTRO变量是否被设置
            如果FSLDISTRO变量也没被设置,给FSLDISTRO变量指定默认值:FSLDISTRO='fsl-imx-xwayland'
        如果设置了DISTRO变量,就设置FSLDISTRO变量等于DISTRO变量内容   

        判断执行脚本时是否设置了构建目录,如果没有设置,使用默认的构建目录,BUILD_DIR=build
        判断执行脚本时是否设置了MACHINE变量,如果MCHINE变量没被设置,使用默认的MACHINE值,MACHINE='imx6qpsabresd'
        判断传入的DISTRO是否支持该MACHINE,如果不支持打印错误信息并退出
     (对于i.MX8系列,只支持DISTRO=fsl-imx-wayland/fsl-imx-xwayland的配置)

3) 切换到$(pwd)/sources/meta-freescale目录
        判断该目录下是否存在一个名字为EULA的软链接文件,如果存在,清除该文件
        判断该目录下的子目录classes中是否存在fsl-eula-unpack.bbclass文件 

4) 切换回之前目录(yocto工程存放目录)

5) FSL_EULA_FILE=$(pwd)/sources/meta-imx/EULA.txt

6) 判断执行脚本时是否设置了DISTRO变量
        如果没设置,以下面方式调用setup-environment脚本
            DISTRO=$FSLDISTRO MACHINE=$MACHINE . ./setup-environment $BUILD_DIR
        否则,以下面方式调用setup-environment脚本
            MACHINE=$MACHINE . ./$setup-environment $BUILD_DIR
        执行脚本传入的参数是构建目录的名称

7) BUILD_DIR=.
    (已经切换到构建目录了,所有BUILD_DIR=.表示当前目录)

8) 判断构建目录下conf目录中local.conf是否存在,如果不存在退出。前面6)中调用了setup-environment,该文件已经被正常创建

9) 判断$BUILD_DIR/conf/local.conf.org文件是否存在,如果第一次执行脚本配置,该文件肯定不存在
        不存在
            拷贝$BUILD_DIR/conf/local.conf文件内容到$BUILD_DIR/conf/local.conf.org文件
        存在
            拷贝$BUILD_DIR/conf/local.conf.org文件内容到$BUILD_DIR/conf/local.conf文件

备份local.conf文件内容到local.conf.org文件原因,避免下面10)中的内容被重复追加到local.conf文件

10) 追加下面信息到conf/local.conf文件
    echo >> conf/local.conf
    echo "# Switch to Debian packaging and include package-management in the image" >> conf/local.conf
    echo "PACKAGE_CLASSES = \"package_deb\"" >> conf/local.conf
    echo "EXTRA_IMAGE_FEATURES += \"package-management\"" >> conf/local.conf

11) 判断$BUILD_DIR/conf/local.conf.org文件是否存在
        不存在
            拷贝$BUILD_DIR/conf/bblayers.conf文件内容到$BUILD_DIR/conf/bblayers.conf.org文件
        存在
            拷贝$BUILD_DIR/conf/bblayers.conf.org文件内容到$BUILD_DIR/conf/bblayers.conf文件

12) META_FSL_BSP_RELEASE="${CWD}/sources/meta-imx/meta-bsp"

13) 追加下面信息到bblayers.conf
    echo "" >> $BUILD_DIR/conf/bblayers.conf
    cho "# i.MX Yocto Project Release layers" >> $BUILD_DIR/conf/bblayers.conf

14) hook_in_layer meta-imx/meta-bsp
    hook_in_layer meta-imx/meta-sdk
    hook_in_layer meta-imx/meta-ml
    hook_in_layer meta-nxp-demo-experience
    追加下面信息到bblayers.conf,同时分别判断meta-imx目录下的meta-bsp、meta-sdk、meta-ml、meta-nxp-demo-experience目录里的conf/machine和conf/machine/include里的配置是否和
    meta-freescale/conf和/meta-freescale/conf/machine/include配置名是否相同,如果相同删除meta-freescale里的该项配置。meta-imx下内容是最新的,是对meta-freescale里的内容的更新和补充
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-imx/meta-bsp\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-imx/meta-sdk\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-imx/meta-ml\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-nxp-demo-experience\"" >> $BUILD_DIR/conf/bblayers.conf

15) 主机下面信息到bblayers.conf
    echo "" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-browser\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-rust\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-clang\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-openembedded/meta-gnome\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-openembedded/meta-networking\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-openembedded/meta-filesystems\"" >> $BUILD_DIR/conf/bblayers.conf

    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-qt5\"" >> $BUILD_DIR/conf/bblayers.conf
    echo "BBLAYERS += \"\${BSPDIR}/sources/meta-python2\"" >> $BUILD_DIR/conf/bblayers.conf

16) echo BSPDIR=$BSPDIR
    echo BUILD_DIR=$BUILD_DIR

17) 如果../sources/meta-freescale目录存在
    echo meta-freescale directory found
    # Change settings according to environment
    sed -e "s,meta-fsl-arm\s,meta-freescale ,g" -i conf/bblayers.conf----------------->conf/bblayers.conf文件中"meta-fsl-arm "替换成"meta-freescale "
    sed -e "s,\$.BSPDIR./sources/meta-fsl-arm-extra\s,,g" -i conf/bblayers.conf------->将conf/bbylayers文件中的"${BSPDIR}/sources/meta-fsl-arm-extra "内容替换为空字符

3、总结

至此,关于执行imx-setup-release.sh脚本完成的工作分析完了。总的概况来说执行该脚本,创建了构建目录下的conf目录下的内容,将构建所要用到的工具集和脚本所在路径添加到了PATH环境变量,并且设置了bitbake构建机制所使用的环境变量。

posted on 2021-03-14 12:57  quinoa  阅读(1428)  评论(0编辑  收藏  举报