#!/bin/bash
|
|
# bitbake target
|
BB_TARGET=yocto-image-full
|
|
# this project absolute path
|
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
|
|
# top project absolute path
|
TOP_PATH=$PRJ_PATH/..
|
|
# prefix install path
|
PRFX_PATH=$PRJ_PATH/install
|
|
# final install path
|
#INST_PATH=/srv/ftp/
|
|
# compress system image or not
|
COMPRESS=yes
|
|
# config file path
|
CONF_FILE=$TOP_PATH/config.json
|
|
# Download path (若取消注释,会自动修改 local.conf 中的 DL_DIR)
|
#DL_PATH="/srv/yocto/"
|
|
# shell script will exit once get command error
|
set -e
|
|
#+-------------------------+
|
#| Shell script functions |
|
#+-------------------------+
|
|
function pr_error() {
|
echo -e "\033[40;31m $1 \033[0m"
|
}
|
|
function pr_warn() {
|
echo -e "\033[40;33m $1 \033[0m"
|
}
|
|
function pr_info() {
|
echo -e "\033[40;32m $1 \033[0m"
|
}
|
|
# parser configure file and export environment variable
|
function export_env()
|
{
|
export BOARD=$(jq -r ".bsp.board" "$CONF_FILE" | tr 'A-Z' 'a-z')
|
export BSP_VER=$(jq -r ".bsp.version" "$CONF_FILE" | tr 'A-Z' 'a-z')
|
export YCT_VER=$(jq -r ".system.version" "$CONF_FILE" | tr 'A-Z' 'a-z')
|
|
export YCT_BOARD=$(echo "$BOARD" | cut -d- -f1)
|
|
# 外部实际存放不同版本 Layer 的根目录:meta-igkboard
|
export YCT_META_BASE=meta-$YCT_BOARD
|
|
# 当前编译版本对应的真实 Layer 源路径:meta-igkboard/wrynose
|
export YCT_META_SRC_DIR=$PRJ_PATH/$YCT_META_BASE/$YCT_VER
|
|
export YCT_SRC=$YCT_VER-$BSP_VER
|
export YCT_PATH=$PRJ_PATH/$YCT_SRC
|
|
# Yocto sources 下期望的实际 Layer 名字:sources/meta-igkboard
|
export YCT_META_TARGET=$YCT_PATH/sources/$YCT_META_BASE
|
|
export BUILD_DIR=${BOARD}
|
}
|
|
function do_fetch()
|
{
|
cd "$PRJ_PATH"
|
|
# 1. 检查外部的实际版本 Layer 目录是否存在 (如 meta-igkboard/wrynose)
|
if [ ! -d "$YCT_META_SRC_DIR" ] ; then
|
pr_error "Local meta layer directory $YCT_META_SRC_DIR does not exist!"
|
return 1
|
fi
|
|
# 2. 拉取 Yocto 源码 (若 sources/base 目录不存在则执行拉取)
|
if [ ! -d "$YCT_PATH/sources/base" ] ; then
|
pr_info "start repo fetch Yocto $YCT_VER source code"
|
|
mkdir -p "$YCT_PATH" && cd "$YCT_PATH"
|
|
if ! command -v repo > /dev/null 2>&1 ; then
|
curl https://storage.googleapis.com/git-repo-downloads/repo > repo
|
chmod a+x repo
|
export PATH=$YCT_PATH:$PATH
|
fi
|
|
local REPO_BSP_VER=$(echo "$BSP_VER" | sed 's/lf/imx/')
|
repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-$YCT_VER -m "${REPO_BSP_VER}.xml"
|
repo sync && rm -f repo
|
else
|
pr_warn "Yocto $YCT_VER source code fetched already"
|
fi
|
}
|
|
# 处理本地 BSP 补丁拷贝及修复 Yocto QA 状态检查
|
function do_patch()
|
{
|
local PATCH_BSP_VER=$(echo "$BSP_VER" | sed 's/imx/lf/')
|
|
local UBOOT_PATCH="$YCT_META_SRC_DIR/recipes-bsp/u-boot/files/uboot-imx-${PATCH_BSP_VER}.patch"
|
local KERNEL_PATCH="$YCT_META_SRC_DIR/recipes-kernel/linux/files/linux-imx-${PATCH_BSP_VER}.patch"
|
|
# 1. 创建 mete-igkboard 符号链接
|
if [ ! -L "$YCT_META_TARGET" ]; then
|
pr_info "Create symlink: $YCT_META_TARGET -> $YCT_META_SRC_DIR"
|
ln -sfn "$YCT_META_SRC_DIR" "$YCT_META_TARGET"
|
fi
|
|
# 2. 只有当目标补丁文件不存在时,才进行拷贝和注入
|
if [ ! -f "$UBOOT_PATCH" ] || [ ! -f "$KERNEL_PATCH" ] ; then
|
pr_warn "Copy u-boot and linux patches..."
|
|
# 确保补丁存放的目标子目录存在
|
mkdir -p "$YCT_META_SRC_DIR/recipes-bsp/u-boot/files"
|
mkdir -p "$YCT_META_SRC_DIR/recipes-kernel/linux/files"
|
|
# 拷贝补丁与配置文件
|
cp "$TOP_PATH/bootloader/patches/${BOARD}/uboot-imx-${PATCH_BSP_VER}.patch" "$YCT_META_SRC_DIR/recipes-bsp/u-boot/files/"
|
cp "$TOP_PATH/kernel/patches/${BOARD}/linux-imx-${PATCH_BSP_VER}.patch" "$YCT_META_SRC_DIR/recipes-kernel/linux/files/"
|
cp "$TOP_PATH/images/patches/config-"*.txt "$YCT_META_SRC_DIR/recipes-bsp/u-boot/files/"
|
|
# 使用 sed 动态注入 Upstream-Status 标签来绕过 Yocto QA 检查
|
pr_info "Injecting Upstream-Status into patches..."
|
|
if [ -f "$UBOOT_PATCH" ]; then
|
sed -i '1i Upstream-Status: Inappropriate [In-house SDK]\n' "$UBOOT_PATCH"
|
fi
|
|
if [ -f "$KERNEL_PATCH" ]; then
|
sed -i '1i Upstream-Status: Inappropriate [In-house SDK]\n' "$KERNEL_PATCH"
|
fi
|
fi
|
}
|
|
function do_build()
|
{
|
cd "$YCT_PATH"
|
|
# 1. 初始化 Yocto 编译环境
|
if [ ! -f "${BUILD_DIR}/conf/local.conf" ] ; then
|
pr_info "source imx-setup-release.sh -b ${BOARD}"
|
EULA=1 DISTRO=fsl-imx-xwayland MACHINE=${BOARD} source imx-setup-release.sh -b ${BOARD}
|
else
|
pr_info "source setup-environment $BUILD_DIR"
|
source setup-environment "$BUILD_DIR"
|
fi
|
|
# 2. 添加自定义的本地 meta layer 到 bblayers.conf
|
if ! bitbake-layers show-layers | grep -q "$YCT_META_BASE" ; then
|
pr_info "Adding custom layer $YCT_META_BASE to bblayers.conf..."
|
bitbake-layers add-layer "$YCT_PATH/sources/$YCT_META_BASE"
|
fi
|
|
# 3. 只有当 DL_PATH 被定义且不为空时,才用 sed 替换 local.conf
|
if [[ -n "${DL_PATH}" ]] ; then
|
sed -i "s|^#DL_DIR.*|DL_DIR ?= \"$DL_PATH/$YCT_VER\"|g" conf/local.conf
|
sed -i "s|^DL_DIR.*|DL_DIR ?= \"$DL_PATH/$YCT_VER\"|g" conf/local.conf
|
fi
|
|
# 4. 执行编译
|
bitbake "$BB_TARGET"
|
}
|
|
function do_install()
|
{
|
local IMAGE_NAME=yocto-${YCT_VER}-${BOARD}.img
|
local ROOTFS_TAR=rootfs-yocto-${YCT_VER}.tar.zst
|
|
cd "$YCT_PATH"
|
|
echo ""
|
pr_info "Yocto($YCT_VER) installed to '$PRFX_PATH'"
|
|
mkdir -p "${PRFX_PATH}"
|
cp "$YCT_PATH/$BUILD_DIR/tmp/deploy/images/$BOARD/$BB_TARGET-$BOARD.wic" "${PRFX_PATH}/$IMAGE_NAME"
|
cp "$YCT_PATH/$BUILD_DIR/tmp/deploy/images/$BOARD/$BB_TARGET-$BOARD.tar.zst" "${PRFX_PATH}/$ROOTFS_TAR"
|
|
if [[ $BOARD =~ mx6ull ]] ; then
|
cp "$YCT_PATH/$BUILD_DIR/tmp/deploy/images/$BOARD/u-boot-${BOARD}.imx" "${PRFX_PATH}/u-boot-${BOARD}.imx"
|
else
|
cp "$YCT_PATH/$BUILD_DIR/tmp/deploy/images/$BOARD/imx-boot" "${PRFX_PATH}/u-boot-${BOARD}.imx"
|
fi
|
|
cd "${PRFX_PATH}/"
|
|
if [[ $(echo "$COMPRESS" | tr 'A-Z' 'a-z') == "yes" ]] ; then
|
pr_info "Start bzip2 compress $IMAGE_NAME"
|
rm -f "$IMAGE_NAME.bz2"
|
bzip2 "$IMAGE_NAME"
|
fi
|
chmod a+x "u-boot-${BOARD}.imx"
|
|
ls && echo ""
|
|
if [ -n "$INST_PATH" ] && [ -w "$INST_PATH" ] ; then
|
pr_info "Start copy Yocto system images to $INST_PATH"
|
cp "u-boot-${BOARD}.imx" "$INST_PATH"
|
cp $IMAGE_NAME* "$INST_PATH"
|
cp "$ROOTFS_TAR" "$INST_PATH"
|
|
ls "${INST_PATH}" && echo ""
|
fi
|
}
|
|
function do_clean()
|
{
|
cd "$PRJ_PATH"
|
rm -rf "$PRFX_PATH"
|
}
|
|
#+-------------------------+
|
#| Shell script body entry |
|
#+-------------------------+
|
|
export_env
|
|
if [[ $# == 1 && $1 == -c ]] ;then
|
pr_warn "start clean Yocto source code"
|
do_clean
|
exit 0
|
fi
|
|
pr_warn "start build Yocto $YCT_VER for ${BOARD}"
|
|
do_fetch
|
|
do_patch
|
|
do_build
|
|
do_install
|