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執行環境,並不是直接在該環境下進行編譯工作,因為該環境下的編譯太慢了;配置該環境,主要是為了能夠更快速,更加便捷的獲取交叉編譯依賴的動態庫,和靜態庫,標頭檔案資訊等。
這部分參考:
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 Ubuntu
上chroot
到~/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_TRY_COMPILER_TARGET_TYPE STATIC_LIBRARY)
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)
這句話的作用,在上述參考連線中的解釋是,為了避免交叉編譯過程中由於嚴格的編譯器檢查而中斷編譯過程。
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上面進行安裝,然後將對應庫拷貝出來即可。