本博客在Ubuntu22.04的虚拟环境中,进行OpenVela的编译并测试

OpenVela快速入门

步骤一:准备工作

在开始之前,请确保您的开发环境满足以下要求。

1. 硬件要求

硬盘: 至少 40 GB 可用空间,用于存放源代码和编译产物。建议大一些,我给了150GB。
内存: 至少 16 GB RAM。

2. 操作系统要求

操作系统: Ubuntu 22.04 (arm64/x86_64) 用户名ubuntu 密码ubuntu
设置静态IP 192.168.100.100
配置镜像源-复制

ubuntu@ubuntu-virtual-machine:~$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

配置镜像源-修改sources.list

ubuntu@ubuntu-virtual-machine:~$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

配置镜像源-设置如下镜像源

deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse

安装必备软件

sudo apt update
sudo apt install net-tools openssh-server vim
sudo apt install \
bison flex gettext texinfo libncurses5-dev libncursesw5-dev xxd \
git gperf automake libtool build-essential gperf genromfs \
libgmp-dev libmpc-dev libmpfr-dev libisl-dev binutils-dev libelf-dev \
libexpat1-dev gcc-multilib g++-multilib picocom u-boot-tools util-linux \
dfu-util libx11-dev libxext-dev net-tools pkgconf unionfs-fuse zlib1g-dev \
libusb-1.0-0-dev libv4l-dev libuv1-dev npm nodejs nasm yasm libdivsufsort-dev \
libc++-dev libc++abi-dev libprotobuf-dev protobuf-compiler protobuf-c-compiler mtools curl

3. 安装开发工具

在开始之前,您需要安装编译 openvela 所需的软件包。

打开终端,执行以下命令,更新软件包列表并安装 Git、CMake、Python 3 和 build-essential 工具链。

sudo apt update
sudo apt install git cmake python3 build-essential
  1. 安装 Git LFS 组件
    说明:本项目包含大体积的二进制文件(如模型权重、数据集)。请务必配置 Git LFS,否则拉取的文件将损坏(仅显示为几 KB 的指针文本)而无法运行。

请在 Ubuntu 终端中执行以下命令进行安装和初始化:

# 第一步:配置官方源并安装 (确保获取最新版)
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs

# 第二步:初始化配置 (重要:必须执行此步,否则 LFS 不会生效)
git lfs install

openvela 配置系统使用 KConfig ,作为 kconfig-frontends 软件包的一部分,KConfig 通过一系列基于交互式菜单的前端对系统进行配置。使用软件包还是从源码构建取决于当前的操作系统,源码地址位于 NuttX tools repository。

sudo apt install kconfig-frontends

安装 Python

sudo apt install python3 python3-pip python-is-python3

步骤五 安装 Python 包

sudo pip3 install kconfiglib pyelftools cxxfilt

步骤二:下载源代码

openvela 使用 repo 工具管理其分布在多个 Git 仓库中的源代码。

1. 安装 Repo 工具

repo 是一个构建于 Git 之上的代码库管理工具。执行以下命令来安全地下载并安装它。

curl -sSL "https://storage.googleapis.com/git-repo-downloads/repo" > repo
chmod +x repo
sudo mv repo /usr/local/bin

安装完成后,可运行 repo --version 进行验证。

2. 初始化并同步代码库

创建一个工作目录,用于存放 openvela 的所有源代码。

mkdir openvela && cd openvela

使用 repo 初始化项目清单,并指定 trunk-5.4 分支。

请根据您的网络环境和偏好,从以下任一平台选择一种方式(推荐使用 SSH)来初始化仓库。

配置gitee

步骤1 : 在ubuntu创建ssh公钥和私钥

ssh-keygen -t ed25519 -C "your_email@example.com"

-t ed25519:指定密钥类型为 ed25519(比 RSA 更安全、效率更高);
-C:备注信息,填你 Gitee 账号的邮箱即可,方便识别密钥用途。

步骤2:执行命令后会出现交互提示:
第一步:Enter file in which to save the key → 直接按回车(使用默认路径 ~/.ssh/id_ed25519);
第二步:Enter passphrase (empty for no passphrase) → 可选设置密钥密码(按回车则无密码,拉取代码时无需输入密码,更方便);
第三步:Enter same passphrase again → 若第二步设了密码,重复输入,否则直接回车。

步骤3:生成秘钥
生成成功后,终端会提示密钥保存路径,默认:
私钥:~/.ssh/id_ed25519(切勿泄露!);
公钥:~/.ssh/id_ed25519.pub(需要配置到 Gitee)。

步骤4:复制公钥内容
执行以下命令快速复制公钥(避免手动复制出错):
bash
运行

cat ~/.ssh/id_ed25519.pub | xclip -sel clip

若提示 xclip 未安装,可以直接复制,也可以执行:

sudo apt update && sudo apt install xclip

再重新复制。
步骤5:配置 Gitee SSH 公钥
登录 Gitee 官网(https://gitee.com/);
点击右上角「头像 → 设置 → SSH 公钥」;
「标题」栏填自定义名称(比如「Ubuntu-ED25519」);
「公钥」栏粘贴刚才复制的内容(直接 Ctrl+V);
点击「确定」,验证 Gitee 密码即可完成配置。
在这里插入图片描述

步骤6:ubuntu配置全局的username和email

# 设置用户名(替换成你的 Gitee 用户名,比如 "zhangsan")
git config --global user.name "你的用户名"

# 设置邮箱(替换成你 Gitee 绑定的邮箱,比如 "zhangsan@example.com")
git config --global user.email "你的邮箱地址"
从 Gitee 下载

方式一:SSH (推荐)

此方式需要您先将 SSH 公钥添加至您的 Gitee 账户,请参考 Gitee 官方文档。

repo init --u ssh://git@gitee.com/open-vela/manifests.git -b trunk -m tags/trunk-5.4.xml --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/ --git-lfs

方式二:HTTPS

repo init -u https://gitee.com/open-vela/manifests.git -b trunk -m tags/trunk-5.4.xml --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/ --git-lfs

3.执行同步命令

执行同步命令,repo 将根据清单文件 (trunk-5.4.xml) 下载所有相关的源代码仓库。

repo sync -c -j8

在这里插入图片描述
在这里插入图片描述

首次同步耗时较长,具体时间取决于您的网络状况和磁盘性能。
若因网络问题中断,可重复执行 repo sync 进行增量同步。

步骤三:编译源代码

完成源代码下载后,请在 openvela 根目录下执行以下编译步骤。

1. (可选)自定义内核配置

您可以通过 menuconfig 命令打开图形化界面,以调整 NuttX 内核与组件的配置。

cd ~/openvela
./build.sh vendor/openvela/boards/vela/configs/goldfish-arm64-v8a-ap/ --cmake menuconfig

在这里插入图片描述

在这里插入图片描述

按 / 键可搜索配置项。
按 空格键 可切换选中状态(启用/禁用/模块化)。
配置完成后,选择 Save 保存并退出。

命令解释如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

查看build.sh脚本文件

ubuntu@ubuntu-virtual-machine:~/openvela$ cat build.sh
#!/usr/bin/env bash
# tools/build.sh
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

function cleanup()
{
  # keep the mapping but change to the link since:
  # 1.root can't access mount point created by normal user
  # 2.debugger could find the source code without manual setting
  fusermount -u ${MOUNTDIR}
  rmdir ${MOUNTDIR}
  ln -s ${ROOTDIR} ${MOUNTDIR}
}

function mount_unionfs()
{
  echo -e "Mount command line:"
  echo -e "  unionfs-fuse -o cow ${OUTDIR}=RW:${ROOTDIR}=RO ${MOUNTDIR}"

  rm -f ${MOUNTDIR}
  mkdir -p ${MOUNTDIR}
  unionfs-fuse -o cow ${OUTDIR}=RW:${ROOTDIR}=RO ${MOUNTDIR}
}

function setup_environment()
{
  PACKAGES=( \
      "autoconf" \
      "automake" \
      "bison" \
      "dfu-util" \
      "flex" \
      "genromfs" \
      "gettext" \
      "git" \
      "gperf" \
      "kconfig-frontends" \
      "make" \
      "mtools" \
      "nasm" \
      "net-tools" \
      "nodejs" \
      "npm" \
      "pkgconf" \
      "protobuf-c-compiler" \
      "protobuf-compiler" \
      "xxd" \
      "yasm" \
      )

  SIM_X86_PACKAGES=( \
      "libasound2-dev:i386" \
      "libasound2-plugins:i386" \
      "libc6-dev-i386" \
      "libmad0-dev:i386" \
      "libmp3lame-dev:i386" \
      "libpulse-dev:i386" \
      "libusb-1.0-0-dev:i386" \
      "libv4l-dev:i386" \
      "libx11-dev:i386" \
      "libxext-dev:i386" \
  )

  SIM_X86_64_PACKAGES=( \
      "libasound2-dev" \
      "libasound2-plugins" \
      "libc6-dev" \
      "libc++abi-dev" \
      "libc++-dev" \
      "libdivsufsort-dev" \
      "libncurses5" \
      "libprotobuf-dev" \
      "libusb-1.0-0-dev" \
      "libuv1-dev" \
      "libv4l-dev" \
      "libx11-dev" \
      "libxext-dev" \
      "zlib1g-dev" \
  )

  QEMU_PACKAGES=( \
      "qemu-system-arm" \
      "qemu-efi-aarch64" \
      "qemu-utils" \
  )

  local boardconfig=$1
  if [ -f ${ROOTDIR}/${boardconfig}/defconfig ]; then
    dconfig=${ROOTDIR}/${boardconfig}/defconfig
  else
    configdir=`echo ${boardconfig} | cut -s -d':' -f2`
    if [ -z "${configdir}" ]; then
      boarddir=`echo ${boardconfig} | cut -d'/' -f1`
      configdir=`echo ${boardconfig} | cut -d'/' -f2`
    else
      boarddir=`echo ${boardconfig} | cut -d':' -f1`
    fi
    configpath=${NUTTXDIR}/boards/*/*/${boarddir}/configs/${configdir}
    dconfig=${configpath}/defconfig
  fi

  if [ ! -r ${dconfig} ]; then
    echo "File ${dconfig} does not exist"
    exit 5
  fi

  if grep -q "CONFIG_ARCH_SIM" $dconfig >/dev/null; then
      if grep -q "CONFIG_SIM_M32" $dconfig >/dev/null; then
          PACKAGES+=("${SIM_X86_PACKAGES[@]}")
      else
          PACKAGES+=("${SIM_X86_64_PACKAGES[@]}")
      fi
  fi
  if grep -q "CONFIG_ARCH_CHIP_QEMU" $dconfig >/dev/null; then
      PACKAGES+=("${QEMU_PACKAGES[@]}")
  fi

  for (( i = 0; i < ${#PACKAGES[*]}; i++)); do
    dpkg -l ${PACKAGES[$i]} > /dev/null 2>&1
    if [ $? -eq 1 ]; then
      echo "WARNING: no packages found matching ${PACKAGES[$i]}"
      INSTALLS[${#INSTALLS[@]}]=${PACKAGES[$i]}
    fi
  done

  if [ ${#INSTALLS[*]} -eq 0 ]; then
    return
  fi

  if [ ${#INSTALLS[*]} -eq 1 ] && [ "${INSTALLS[0]}" == "kconfig-frontends" ]; then
    return
  fi

  echo "*************************************************************************************"
  echo "The environment of Vela depends on above tools, Run the following command to install:"
  echo ""

  for (( i = 0; i < ${#INSTALLS[*]}; i++)); do
    if [[ "${INSTALLS[$i]}" == *":i386" ]]; then
      echo " sudo dpkg --add-architecture i386"
      break
    fi
  done

  for (( i = 0; i < ${#INSTALLS[*]}; i++)); do
    result=`apt-cache search ${INSTALLS[$i]}`
    if [ "$result" == "" ]; then
      if [ "${INSTALLS[$i]}" == "kconfig-frontends" ]; then
        unset INSTALLS[$i]
      fi
    fi
  done

  echo " sudo apt-get update"
  echo " sudo apt-get install -y ${INSTALLS[@]}"
  echo ""
  echo "*************************************************************************************"
}

function setup_toolchain()
{
  V='\033[0;97m'
  E='\033[0;94m'
  L='\033[0;96m'
  A='\033[0;94m'
  B='\033[0;34m'
  N='\033[0m'
  echo -e "${B}**""**""**""**""**""**""**""**""**""**""**""**""**""***${N}"
  echo -e "${B}*${V} __      __   ${E}   ""${L}_ ${A}      "   " ${B}*${N}"
  echo -e "${B}* ${V}\\ \\    / /${E}     ${L}| |${A}      "   " ${B}*${N}"
  echo -e "${B}*  ${V}\\ \\  / /${E} ___  ${L}| |${A}  __ _"   " ${B}*${N}"
  echo -e "${B}*   ${V}\\ \\/ /${E} / _ \\ ${L}| |${A} / _\` |" "${B}*${N}"
  echo -e "${B}*    ${V}\\  / ${E}|  __/ ${L}| |${A}| (_| |"    "${B}*${N}"
  echo -e "${B}*     ${V}\\/ ${E}  \\___| ${L}|_|${A} \\__,_|"  "${B}*${N}"
  echo -e "${B}*           "                         "               *${N}"
  echo -e "${B}**""**""**""**""**""**""**""**""**""**""**""**""**""***${N}"

  SYSTEM=`uname | tr '[:upper:]' '[:lower:]'`
  SYS_ARCH=`uname -m | sed 's/arm64/aarch64/'`

  if [ ${SYSTEM} == "darwin" ]; then
    export MACOSX_DEPLOYMENT_TARGET=11
    BONJOUR=" Welcome, dear macOS user "
    for ((i=0;i<${#BONJOUR};i++)); do
      printf "\e[38;5;$(($RANDOM%213+19))m${BONJOUR:i:1}\e[0m"
    done
    echo #
  fi

  ARCH=(\
      "xtensa" \
      "arm" \
      "arm64" \
      "aarch64" \
      "riscv" \
      "risc-v" \
      "x86_64" \
      "tc32" \
      "tricore")

  TOOLCHAIN=(\
            "gcc" \
            "clang" )

  if [ "$XTENSAD_LICENSE_FILE" == "" ]; then
    export XTENSAD_LICENSE_FILE=28000@0.0.0.0
  fi
  # WASI SDK is clang based toolchain to build WebAssembly targets
  export WASI_SDK_PATH=${ROOTDIR}/prebuilts/clang/${SYSTEM}/wasm
  # Wasm toolchain is used to optimize wasm binaries
  export WASM_TOOLCHAIN_PATH=${ROOTDIR}/prebuilts/clang/${SYSTEM}/wasm
  export PYTHONPATH=${PYTHONPATH}:${ROOTDIR}/prebuilts/tools/python/dist-packages/pyelftools
  export PYTHONPATH=${PYTHONPATH}:${ROOTDIR}/prebuilts/tools/python/dist-packages/cxxfilt
  export PYTHONPATH=${PYTHONPATH}:${ROOTDIR}/prebuilts/tools/python/dist-packages/Mako
  export PYTHONPATH=${PYTHONPATH}:${ROOTDIR}/prebuilts/tools/python/dist-packages/ply
  export PYTHONPATH=${PYTHONPATH}:${ROOTDIR}/prebuilts/tools/python/dist-packages/jsonpath
  export PYTHONPATH=${PYTHONPATH}:${ROOTDIR}/prebuilts/tools/python/dist-packages/kconfiglib
  export PYTHONPATH=${PYTHONPATH}:${ROOTDIR}/prebuilts/tools/python/dist-packages/construct

  # Recommended to use kconfiglib instead of kconfig-frontends
  export PATH=${ROOTDIR}/prebuilts/tools/python/bin:$PATH

  for (( i = 0; i < ${#ARCH[*]}; i++)); do
    for (( j = 0; j < ${#TOOLCHAIN[*]}; j++)); do
      if [ -d ${ROOTDIR}/prebuilts/${TOOLCHAIN[$j]}/${SYSTEM}-${SYS_ARCH}/${ARCH[$i]}/bin ]; then
        export PATH=${ROOTDIR}/prebuilts/${TOOLCHAIN[$j]}/${SYSTEM}-${SYS_ARCH}/${ARCH[$i]}/bin:$PATH
      elif [ -d ${ROOTDIR}/prebuilts/${TOOLCHAIN[$j]}/${SYSTEM}/${ARCH[$i]}/bin ]; then
        export PATH=${ROOTDIR}/prebuilts/${TOOLCHAIN[$j]}/${SYSTEM}/${ARCH[$i]}/bin:$PATH
      fi
      if [ -d ${ROOTDIR}/prebuilts/${TOOLCHAIN[$j]}/${SYSTEM}-${SYS_ARCH}/${ARCH[$i]}-none-linux-gnu/bin ]; then
        export PATH=${ROOTDIR}/prebuilts/${TOOLCHAIN[$j]}/${SYSTEM}-${SYS_ARCH}/${ARCH[$i]}-none-linux-gnu/bin:$PATH
      fi
      for TOOLCHAIN_BIN in ${ROOTDIR}/prebuilts/${TOOLCHAIN[$j]}/${SYSTEM}-${SYS_ARCH}/${ARCH[$i]}{,-none}-{eabi,elf}/bin; do
          if [ -d ${TOOLCHAIN_BIN} ]; then
              export PATH=${TOOLCHAIN_BIN}:$PATH
          fi
      done
    done
  done

  # Arm Compiler
  export PATH=${ROOTDIR}/prebuilts/clang/${SYSTEM}/armclang/bin:$PATH

  if [ ! -n "${ARM_PRODUCT_DEF}" ]; then
    export ARM_PRODUCT_DEF=${ROOTDIR}/prebuilts/clang/${SYSTEM}/armclang/mappings/eval.elmap
  fi
  if [ ! -n "${LM_LICENSE_FILE}" ]; then
    export LM_LICENSE_FILE=${HOME}/.arm/ds/licenses/DS000-EV-31030.lic
  fi
  if [ ! -n "${ARMLMD_LICENSE_FILE}" ]; then
    export ARMLMD_LICENSE_FILE=${HOME}/.arm/ds/licenses/DS000-EV-31030.lic
  fi

  # Host build-tools
  if [ -d ${ROOTDIR}/prebuilts/build-tools/${SYSTEM}-${SYS_ARCH}/bin ]; then
    export PATH=${ROOTDIR}/prebuilts/build-tools/${SYSTEM}-${SYS_ARCH}/bin:$PATH
  fi

  # Generate compile database file compile_commands.json
  if type bear >/dev/null 2>&1; then
    # get version of bear
    BEAR_VERSION=$(bear --version | awk '{print $2}' | awk -F. '{printf("%d%03d%03d ", $1,$2,$3)}')

    # judge version of bear
    if [ $BEAR_VERSION -ge 3000000 ]; then
        # BEAR="bear --append --output compile_commands.json -- "
        echo -e "Note: currently not support bear 3.0.0+ for some prebuilt toolchain limited."
    else
        echo -e "Note: bear 2.4.3 in Ubuntu 20.04 works out of box."
        COMPILE_COMMANDS_DB_PATH="${ROOTDIR}/compile_commands"
        if [ ! -d "$COMPILE_COMMANDS_DB_PATH" ]; then
            mkdir -p $COMPILE_COMMANDS_DB_PATH
        fi

        COMPILE_COMMANDS=${ROOTDIR}/compile_commands.json
        COMPILE_COMMANDS_BACKUP=${COMPILE_COMMANDS_DB_PATH}/compile_commands_${1//\//_}_$(date "+%Y-%m-%d-%H-%M-%S").json
        BEAR="bear -a -o ${COMPILE_COMMANDS} "
    fi
  fi

  # Add prebuilt tool
  TOOLS_DIR=${ROOTDIR}/prebuilts/tools/${SYSTEM}/${SYS_ARCH}
  export PATH="${TOOLS_DIR}:$PATH"

  # Add CMake prebuilt
  export PATH=${ROOTDIR}/prebuilts/tools/cmake/bin:$PATH
  export PATH=${ROOTDIR}/prebuilts/tools/ninja/bin:$PATH

  # Additional prebuilt GNU tools
  if [ ${SYSTEM} == "darwin" ]; then
    export PATH=${ROOTDIR}/prebuilts/tools/gnu/${SYSTEM}/${SYS_ARCH}:$PATH
    export PATH=${ROOTDIR}/prebuilts/tools/gnu/${SYSTEM}/universal:$PATH
  fi
}

function build_board()
{
  echo -e "Build command line:"
  echo -e "  ${TOOLSDIR}/configure.sh -e $1"
  echo -e "  make -C ${NUTTXDIR} EXTRAFLAGS="$EXTRA_FLAGS" ${@:2}"
  echo -e "  make -C ${NUTTXDIR} savedefconfig"

  KCONFIG_ARGS="--enable-mconf --disable-nconf --disable-gconf --disable-qconf"
  if [ `uname` == "Darwin" ]; then
    KCONFIG_ARGS+=" --disable-shared --enable-static"
  fi

  if [ ! -f "${ROOTDIR}/prebuilts/kconfig-frontends/bin/kconfig-conf" ] &&
     [ ! -x "$(command -v kconfig-conf)" ]; then
    pushd ${ROOTDIR}/prebuilts/kconfig-frontends
    ./configure --prefix=${ROOTDIR}/prebuilts/kconfig-frontends ${KCONFIG_ARGS} 1>/dev/null
    touch aclocal.m4 Makefile.in
    make install 1>/dev/null
    popd
  fi
  export PATH=${ROOTDIR}/prebuilts/kconfig-frontends/bin:$PATH

  setup_toolchain $1

  if ! ${TOOLSDIR}/configure.sh -e $1; then
    echo "Error: ############# config ${1} fail ##############"
    exit 1
  fi

  if [[ ${CUSTOM_COMPILER} == "tasking" ]]; then
    kconfig-tweak --file ${NUTTXDIR}/.config --enable CONFIG_TRICORE_TOOLCHAIN_TASKING
  fi

  GHS_OPTS_STRING="CONFIG_ARCH_TOOLCHAIN_GHS=y"
  TASKING_OPTS_STRING="CONFIG_TRICORE_TOOLCHAIN_TASKING=y"
  if grep -qE "^(${GHS_OPTS_STRING}|${TASKING_OPTS_STRING})$" "${NUTTXDIR}/.config"; then
    echo "EXTRA_FLAGS are required to update the when using the GHS or Tasking toolchain."
    EXTRA_FLAGS=$(echo "$EXTRA_FLAGS" | sed 's/-Wno-cpp//' | xargs)
  fi

  if ! ${BEAR} make -C ${NUTTXDIR} EXTRAFLAGS="$EXTRA_FLAGS" ${@:2}; then
    echo "Error: ############# build ${1} fail ##############"
    exit 2
  else
    if [ -f "${COMPILE_COMMANDS}" ]; then
      cp ${COMPILE_COMMANDS} ${COMPILE_COMMANDS_BACKUP}
    fi
  fi

  if echo "${@:2}" | grep -q "distclean"; then
    if [ -f "${COMPILE_COMMANDS}" ]; then
      rm -rf ${COMPILE_COMMANDS}
    fi
    return;
  fi

  if ! make -C ${NUTTXDIR} savedefconfig; then
    echo "Error: ############# save ${1} fail ##############"
    exit 3
  fi

  if [ ! -d $1 ]; then
    cp ${NUTTXDIR}/defconfig ${ROOTDIR}/nuttx/boards/*/*/${1/[:|\/]//configs/}
  else
    if grep -q "#include" "$1/defconfig"; then
      echo "Note: skipping savedefconfig for debug defconfig."
    else
      cp ${NUTTXDIR}/defconfig $1
    fi
  fi
}

function build_board_cmake()
{
  # first check if the command target is `distclean`
  # cmake is built for out-of-tree, so delete the CMAKE_BINARY_DIR directory directly
  if echo "${@:2}" | grep -q "distclean"; then
    echo -e "Build target distclean:"
    echo -e "  there is no need to distclean in cmake, delete '${CMAKE_BINARY_DIR}' directly"
    if [ -d "${CMAKE_BINARY_DIR}" ]; then
      rm -rf $CMAKE_BINARY_DIR
    fi
    return 0
  fi
  # check parallelism
  j_arg=$(echo ${@:2} |grep -oP '\-j[0-9]+')
  # import environmeni
  setup_toolchain $1
  # cmake verbose
  v_arg=""

  # remove the -Wno-cpp build option from ghs build options
  GHS_OPTS_STRING="CONFIG_ARM_TOOLCHAIN_GHS=y"
  TASKING_OPTS_STRING="CONFIG_TRICORE_TOOLCHAIN_TASKING=y"
  defconfig_path=$1/defconfig
  valid_defconfig_path=$(echo ${defconfig_path} | sed 's/^.\{3\}//')
  if grep -qE "^(${GHS_OPTS_STRING}|${TASKING_OPTS_STRING})$" "${valid_defconfig_path}"; then
    echo "EXTRA_FLAGS are required to update the when using the GHS toolchain."
    EXTRA_FLAGS=$(echo "$EXTRA_FLAGS" | sed 's/-Wno-cpp//' | xargs)
  fi

  # check if cmake configuration is required
  if [ ! -d "${CMAKE_BINARY_DIR}" ]; then
    echo -e "Build CMake configuration:"
    echo -e "  cmake -B ${CMAKE_BINARY_DIR} -S ${NUTTXDIR} -DBOARD_CONFIG=$1 -DEXTRA_FLAGS=\"${EXTRA_FLAGS}\" ${CMAKE_GENERATOR}"
    if ! cmake -B ${CMAKE_BINARY_DIR} -S ${NUTTXDIR} -DBOARD_CONFIG=$1 -DEXTRA_FLAGS="${EXTRA_FLAGS}" ${CMAKE_GENERATOR}; then
      echo "Error: ############# config ${1} fail ##############"
      exit 1
    fi
  fi
  # check if the command target is `Xconfig`
  for arg in "${@:2}"
  do
    if [[ $arg == *config ]]; then
      echo -e "  cmake --build ${CMAKE_BINARY_DIR} -t $arg"
      if ! cmake --build ${CMAKE_BINARY_DIR} -t $arg; then
        echo "Error: ############# CMake -t $arg fail ##############"
        exit 2
      else
        return 0
      fi
    fi
    if [[ "$arg" =~ ^V=1$ ]]; then
      v_arg+="-v"
    fi
  done
  # do cmake build
  echo -e "  cmake --build ${CMAKE_BINARY_DIR} $j_arg $v_arg"
  if ! ${BEAR} cmake --build ${CMAKE_BINARY_DIR} $j_arg $v_arg; then
    echo "Error: ############# build ${1} fail ##############"
    exit 2
  else
    if [ -f "${COMPILE_COMMANDS}" ]; then
      cp ${COMPILE_COMMANDS} ${COMPILE_COMMANDS_BACKUP}
    fi
  fi
}


function setup_cmake_binary_dir()
{
  local boardconfig=$1
  if [ -d ${ROOTDIR}/${boardconfig} ]; then
    # parse path config
    config_name=$(basename "$boardconfig")
    board_name=$(basename $(dirname $(dirname "$boardconfig")))
  else
    # parse nuttx config pair
    config_name=`echo ${boardconfig} | cut -s -d':' -f2`
    if [ -z "${config_name}" ]; then
      board_name=`echo ${boardconfig} | cut -d'/' -f1`
      config_name=`echo ${boardconfig} | cut -d'/' -f2`
    else
      board_name=`echo ${boardconfig} | cut -d':' -f1`
    fi
  fi
  CMAKE_BINARY_DIR+="/${board_name}_${config_name}"
}

if [ $# == 0 ]; then
  echo "Usage: $0 [-m] <board-name>:<config-name> [-e <extraflags>] [--cmake] [-b <cmake_binary_dir>] [--dis-ninja] [make options]"
  echo ""
  echo "Where:"
  echo "  -m: out of tree build. Or default in tree build without it."
  echo "  -e: pass extra c/c++ flags such as -Werror via make command line"
  echo "  --cmake: switch the build mode to CMake compilation."
  echo "  -b: set custom binary directory for CMake."
  echo "  --dis-ninja: disable CMake Ninja generator fo default."
  echo "  -c: set custom toolchain."
  exit 1
fi

ROOTDIR=$(dirname $(readlink -f ${0}))
ROOTDIR=$(realpath ${ROOTDIR}/../..)

CONFIGPATH=$2

if [ $1 == "-m" ]; then
  # out of tree build
  confparams=(${CONFIGPATH//:/ })
  configdir=${confparams[1]}

  if [ -z "${configdir}" ]; then
    # handle cases where the end is a "/"
    if [ "${CONFIGPATH:(-1)}" = "/" ]; then
      CONFIGPATH=${CONFIGPATH:0:-1}
    fi
    boarddir=`echo ${CONFIGPATH} | rev | cut -d'/' -f3 | rev`
    configdir=`echo ${CONFIGPATH} | rev | cut -d'/' -f1 | rev`
  else
    boarddir=${confparams[0]}
  fi

  OUTDIR=${ROOTDIR}/out/${boarddir}/${configdir}
  MOUNTDIR=${OUTDIR}/.unionfs
  NUTTXDIR=${MOUNTDIR}/nuttx

  trap cleanup EXIT
  mount_unionfs
  shift
else
  # in tree build
  OUTDIR=${ROOTDIR}
  NUTTXDIR=${ROOTDIR}/nuttx
fi

TOOLSDIR=${NUTTXDIR}/tools
board_config=$1
shift

setup_environment $board_config

EXTRA_FLAGS="-Wno-cpp -Wno-deprecated-declarations"
while [[ "$1" == "-e" ]]; do
  shift
  EXTRA_FLAGS+=" $1"
  echo "extraflags: $EXTRA_FLAGS"
  shift
done

if [ "$1" == "--cmake" ]; then
  CMAKE_BINARY_DIR="cmake_out"
  CMAKE_GENERATOR="-GNinja"
  CMAKE_BUILD="cmake"
  setup_cmake_binary_dir $board_config
  shift
fi

if [ "$1" == "-b" ]; then
  shift
  CMAKE_BINARY_DIR="$1"
  echo "custom CMake binary dir: $CMAKE_BINARY_DIR"
  shift
fi

if [ "$1" == "--dis-ninja" ]; then
  CMAKE_GENERATOR=""
  shift
fi

if [ "$1" == "-c" ]; then
  shift
  CUSTOM_COMPILER="$1"
  echo "custom toolchain: $CUSTOM_COMPILER"
  shift
fi

if [ -d ${ROOTDIR}/${board_config} ]; then
  if [ -z "$CMAKE_BUILD" ]; then
    build_board ${ROOTDIR}/${board_config} $*
  else
    build_board_cmake ../${board_config} $*
  fi
else
  if [ -z "$CMAKE_BUILD" ]; then
    build_board ${board_config} $*
  else
    build_board_cmake ${board_config} $*
  fi
fi

ubuntu@ubuntu-virtual-machine:~/openvela$

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2. 执行编译

编译前的目录
在这里插入图片描述

执行以下命令,构建整个项目。

./build.sh vendor/openvela/boards/vela/configs/goldfish-arm64-v8a-ap/ --cmake -j$(nproc)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

编译成功后,您将在 cmake_out/vela_goldfish-arm64-v8a-ap 目录下找到 nuttx 等编译产物。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ubuntu@ubuntu-virtual-machine:~/openvela$ ll cmake_out/vela_goldfish-arm64-v8a-ap/vela_ap*
-rwxrwxr-x 1 ubuntu ubuntu 64550296  33 17:03 cmake_out/vela_goldfish-arm64-v8a-ap/vela_ap.bin*
-rwxrwxr-x 1 ubuntu ubuntu 64550296  33 17:03 cmake_out/vela_goldfish-arm64-v8a-ap/vela_ap.elf*
ubuntu@ubuntu-virtual-machine:~/openvela$ file cmake_out/vela_goldfish-arm64-v8a-ap/vela_ap.elf
cmake_out/vela_goldfish-arm64-v8a-ap/vela_ap.elf: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=80e432b908c5546fe7ff8fb0fbca8cfcadab5606, with debug_info, not stripped

# 进入编译输出目录
cd cmake_out/vela_goldfish-arm64-v8a-ap/

# 用 QEMU 启动 vela_ap.elf(goldfish 虚拟板专用命令)
qemu-system-aarch64 -machine goldfish64 -cpu cortex-a53 -kernel vela_ap.elf -serial stdio -nographic

步骤四:运行模拟器

先安装

sudo apt update && sudo apt install -y android-tools-adb

在 openvela 根目录下,执行以下脚本启动 Vela Emulator 并加载您的编译产物。

./emulator.sh cmake_out/vela_goldfish-arm64-v8a-ap/

模拟器启动后,您将看到 goldfish-armv8a-ap> 提示符,表明 openvela 已成功运行。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐