x86 Ubuntu 交叉编译 aarch64(ARM64, jetson) CUDA依赖程序

x86 Ubuntu 交叉编译 aarch64(ARM64) CUDA依赖程序

0 文档说明

该文档用来记录如何从零开始构建一个能够编辑CUDA依赖程序的交叉编译环境,并完成交叉编译工作。

1 环境准备

1.1 操作系统及硬件

  • 安装有ubuntu 18.04 x86的物理机或虚拟机:此处ubuntu系统版本的选择和目标aarch64(jetson平台)相同(不相同的话没试过);
  • 一台已有的jetson;(用于配置的aarch64 ubuntu环境安装的库异常的时候,需要在jetson上面进行安装,并获取对应的库文件);

1.2 安装软件

1.2.1 配置aarch64 ubuntu运行环境

需要注意的是:此处配置aarch64 ubuntu运行环境,并不是直接在该环境下进行编译工作,因为该环境下的编译太慢了;配置该环境,主要是为了能够更快速,更加便捷的获取交叉编译依赖的动态库,和静态库,头文件信息等。

这部分参考:从0开始使用QEMU模拟ARM开发环境之定制Ubuntu rootfs(根文件系统)_墨1024的博客-CSDN博客_qemu rootfs

QEMU是一套由法布里斯·贝拉(Fabrice Bellard)所编写的以GPL许可证分发源码的模拟处理器软件,在GNU/Linux平台上使用广泛。

整个配置的基本过程如下:

  • 下载文件:ubuntu-base-18.04.5-base-arm64.tar.gz,地址为Ubuntu官网

  • x84 ubuntu系统上新建rootfs目录,并将上述压缩包解压到该目录:
    $ mkdir ~/rootfs以及$ tar -zxf ubuntu-base-18.04.5-base-arm64.tar.gz -C ~/rootfs

  • 安装qemu包:$ sudo apt-get install qemu qemu-user-static binfmt-support debootstrap

  • 注册aarch64 ubuntu运行环境:$ sudo update-binfmts --enable qemu-aarch64

  • 为了能在x86 Ubuntuchroot~/rootfs并执行aarch64的程序,需要将qemu-aarch64-static拷贝到~/rootfs/usr/bin/
    $ cp -av /usr/bin/qemu-aarch64-static ~/rootfs/usr/bin/

  • 配置arrch64 Ubuntu的网关,与x86 Ubuntu共享网络$ cp /etc/resolv.conf ~/rootfs/etc/resolv.conf

  • 编写运行脚本$ gedit ~/mount.sh

    #!/bin/bash
    mnt() {
    	echo "MOUNTING"
    	sudo mount -t proc /proc ${2}proc
    	sudo mount -t sysfs /sys ${2}sys
    	sudo mount -o bind /dev ${2}dev
    	sudo mount -o bind /dev/pts ${2}dev/pts
    	sudo chroot ${2}
    }
    umnt() {
    	echo "UNMOUNTING"
    	sudo umount ${2}proc
    	sudo umount ${2}sys
    	sudo umount ${2}dev/pts
    	sudo umount ${2}dev
    }
    
    if [ "$1" == "-m" ] && [ -n "$2" ] ;
    then
    	mnt $1 $2
    elif [ "$1" == "-u" ] && [ -n "$2" ];
    then
    	umnt $1 $2
    else
    	echo ""
    	echo "Either 1'st, 2'nd or both parameters were missing"
    	echo ""
    	echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
    	echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
    	echo ""
    	echo "For example: ch-mount -m /media/sdcard/"
    	echo ""
    	echo 1st parameter : ${1}
    	echo 2nd parameter : ${2}
    fi
    
  • 设置权限:$ sudo chmod +x mount.sh

  • 进入aarch64 ubuntu系统:$ source mount.sh -m ~/rootfs/

  • 退出aarch64 ubuntu系统:$ source mount.sh -u ~/rootfs/注意:进入aarch64 Ubuntu后,不要直接关闭终端,必须先exit内部终端,然后外部终端执行退出命令,否则x86 Ubuntu终端不可用了

  • 进入aarch64 ubuntu之后,需要配置源,参见ubuntu arm/arm64搭建和更改为国内源_汉文修士的博客-CSDN博客_ubuntuarm64源

  • apt update之后可以用apt install安装需要的库;

1.2.2 利用SDK Manager安装cuda

这里可以利用nvidia自带的sdk manager安装cuda环境。下载地址见:NVIDIA SDK Manager | NVIDIA Developer。安装完sdk manager之后

在sdk manager中选择如下安装包,按照步骤进行安装即可。

2 交叉编译

2.1 安装编译工具

注意:关于自带的cmake版本过低,可以自行到Download | CMake官网下载合适的版本即可。

x86 ubuntu中编译aarch64架构的软件,需要先安装对应的编译工具,如下:

$ sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu

安装完之后,会在bin下多出两个可执行文件,/usr/bin/aarch64-linux-gnu-gcc/usr/bin/aarch64-linux-gnu-g++。交叉编译的工作就是需要这个执行文件完成。同时,在usr目录下还会多出一个目录,/usr/aarch64-linux-gnu,该目录下面存储了aarch64架构下的链接库。

2.2 配置交叉编译toolchain.cmake

改文件参考了:https://docs.nvidia.com/vpi/sample_cross_aarch64.html

# ref: https://docs.nvidia.com/vpi/sample_cross_aarch64.html
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnc-g++)

set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)

set(CMAKE_CUDA_FLAGS "-ccbin ${CMAKE_CXX_COMPILER} -Xcompiler -fPIC" CACHE STRING "" FORCE)

这里有个需要关注的点是配置了,CMAKE_CUDA_FLAGS,其中对ccbin参数设置为${CMAKE_CXX_COMPILER},这个目的是设置nvcc执行过程中回调用的编译器,如果没有这个,那么生成得到.o文件将是host 机器(x86)平台下面的。

参考中的set(CMAKE_TRY_COMPILER_TARGET_TYPE STATIC_LIBRARY)这句话可以不需要,加上的话cmake的时候cuda检测会通不过。

2.3 执行编译

cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ../

是不是这样就完事ok了。其实并不然。在编译过程中会出现很多链接库缺失的问题。这个时候就需要进入aarch64 ubuntu环境安装对应的库,并将安装后的头文件,库文件拷贝到/usr/aarch64-linux-gnu/lib目录下(或/usr/aarch64-linux-gnu/usr/lib,用于将后面拷贝的和原始带的库进行区分),头文件放到/usr/aarch64-linux-gnu/include/中。当然我们的头文件查找方式设置的是set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH),如果在host系统目录下能够找到,那么可以不用进行拷贝。另外还需要注意的是,在aarch64 ubuntu环境下安装的库存在异常的可能,那么可以在jetson上面进行安装,然后将对应库拷贝出来即可。

posted @ 2022-04-21 13:27  grassofsky  阅读(4816)  评论(2编辑  收藏  举报