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 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_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上面進行安裝,然后將對應庫拷貝出來即可。