zoukankan      html  css  js  c++  java
  • 有关Xavier交叉编译环境那些事

    前言

    最近公司升级交叉编译环境,需要配置的目标机为Nvidia AGX xavier with Jetpack 4.5这里记录一些坑。

    正文

    总体概要

    所谓cross-compile其实就是在amd64(下称host)上生成arm64(下称target)的binary
    明确一点,所有与编译相关的工具都是运行在本地,比如cmake比如aarch64-gcc比如tclsh版本为host
    而对应的rootfs可以简单理解为库,所有编译过程中需要的.so .a都会在rootfs里面找,版本为target
    至于cuda这种比较特殊的交叉编译,就需要host_bin(例如nvcc)+ target_lib(例如libcublas.so)进行配合
    莫慌,上述这些Nvidia SDK manager会提供下载。

    前期准备

    从SDKmanager下载到的sample rootfs里面不含任何nv三方库,需要自己安装deb
    通过SDK manager可以下载对应型号的rootfs+三方库以及CUDA交叉环境,其中的json文件将指导每个deb的具体安装
    host这边安装好cmake, autoconf, automake, libtool, m4 and tclsh这些编译相关工具,准备好与target一致的aarch64-gcc-7.5

    仿真环境

    使用qemu对target环境进行模拟,对应命令sudo apt install qemu-user-static注意不要装错了
    至此host已经具备执行target bin的能力,直接chroot将报错failed to run command ‘/bin/bash’: No such file or directory
    复制对应的文件sudo cp /usr/bin/qemu-aarch64-static <rootfs>/usr/bin/
    有了这两步就可以chroot到target rootfs进行操作sudo chroot <rootfs> /bin/bash
    成功后使用uname -a检查架构是否为aarch64

    装依赖库

    理论上我们可以通过chroot + qemu的方式进入target rootfs进行包管理apt install ...但这样比较费时费力
    更糟糕的是,现阶段SDK manager刷机后半段会通过ssh访问Xavier安装一些在线内容,如此一来本地deb安装可能不全
    我个人建议使用sample_rootfs作为底包并从刷好的Xavier迁移/usr /lib /opt /etc进行覆盖升级
    完成后更新整个rootfs的符号链接为相对路径symlinks -cr /
    此举可避免编译过程中rootfs中的文件链接到host 效果如下:
    更新前<rootfs>/etc/resolv.conf -> /run/resolvconf/resolv.conf
    更新后<rootfs>/etc/resolv.conf -> ../run/resolvconf/resolv.conf

    打包技巧

    可以使用fakeroot替代sudo实现对rootfs的去权限打包,解压也不再需要root权限。

    交叉编译

    这里提供两种思路:

    1. 编写交叉编译专用CMakeists参考cmake-toolchains(7)
    2. 编写通用CMakeLists通过传入外置-DCMAKE_TOOLCHAIN_FILE=xxx.cmake参数控制platform类型,使得多种架构复用同一套native CMakeLists变为可能

    个人倾向第二种,典型的Linux交叉编译toolchain.cmake包含如下信息:

    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_PROCESSOR arm)
    
    set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
    set(CMAKE_STAGING_PREFIX /home/devel/stage)
    
    set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf)
    set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
    set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)
    
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
    

    奇技淫巧

    对于编译过程中可能遇到的三方依赖,尽量使用cmake官方find_package提供的Modules如FindCUDA.cmake
    官方版本经过迭代能很好的适应三方库因更新引入的文件结构变化,不用自己费心处理
    而对于某些没有官方实现的package则需要自己编写,例如FindTensorRT.cmake其中就有不小的坑
    原先trt5中nvonnxparser_runtime在trt7中已经弃用,比较简单的方法是强制版本>=7
    若希望保留向前兼容能力,需要通过正则表达式提取NvInfer.hNvInferVersion.h中的版本号进行区别处理

    展望

    本质上只要是ubuntu-18.04-aarch64的平台可以复用一套basic rootfs节省硬盘空间
    特化项目所需lib与gcc全部外置,通过cmake参数传入搜索路径,实现模块化管理!
    最后,期待有朝一日Nvidia放出一套类似MDC的交叉编译全家桶!

  • 相关阅读:
    Kubernetes 集群日志管理
    登录功能通用测试用例设计
    Linux常用命令大全
    查看Android应用包名、Activity的几个方法
    CentOS 7 下Docker的安装
    Centos7.1下Docker的安装-yum方法
    appium+Java+testng自动化框架搭建-第一季
    Android在Win10环境搭建
    List<Map<String, Integer>> 同key的value全部累加合并
    Restrictions用法
  • 原文地址:https://www.cnblogs.com/azureology/p/15031031.html
Copyright © 2011-2022 走看看