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的交叉编译全家桶!

  • 相关阅读:
    String类型作为方法的形参
    [转] 为什么说 Java 程序员必须掌握 Spring Boot ?
    Centos打开、关闭、结束tomcat,及查看tomcat运行日志
    centos中iptables和firewall防火墙开启、关闭、查看状态、基本设置等
    防火墙没有关导致外部访问虚拟机的tomcat遇到的问题和解决方法
    可以ping通ip地址,但是访问80,或者8080报错
    JAVA的非对称加密算法RSA——加密和解密
    CA双向认证的时候,如果一开始下载的证书就有问题的,怎么保证以后的交易没有问题?
    图解HTTPS协议加密解密全过程
    https单向认证服务端发送到客户端到底会不会加密?
  • 原文地址:https://www.cnblogs.com/azureology/p/15031031.html
Copyright © 2011-2022 走看看