由于工作需要,在现场调试时需要在笔记本中修改代码,然后将源码拷贝到Jetson Nano中编译(或者自带一台Jetson Nano、显示屏和无线键鼠等,在现场接好后修改和编译代码)。但是由于现场环境条件有限,无论哪种方式都极其不便,极大的降低了工作效率。因此,我决定尝试在笔记本虚拟机中实现Jetson Nano的交叉编译。
虚拟机:VMware® Workstation 15 Pro
操作系统:Ubuntu 18.04.4 LTS
嵌入式设备:Jetson Nano(L4T 32.4.3)
编译工具:QT Creator4.5.2 Based on Qt 5.9.5 (GCC 7.3.0, 64 bit)
mkdir ~/qt_jnano
mkdir ~/qt_jnano/sysroot
mkdir ~/qt_jnano/qt5build
下载并解压交叉编译工具链:
cd ~/qt_jnano/
wget http://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz
tar -xf gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz
为交叉编译工具链创建环境变量:
export PATH=$PATH:/home/smuvision/qt_jnano/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin
vim ~/.bashrc
#在最后一行添加:
export PATH=$PATH:/home/smuvision/qt_jnano/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin
#检查环境变量是否添加
echo $PATH
#查看交叉编译工具链版本
aarch64-linux-gnu-g++ -v
下载并解压qt源码:
cd ~/qt_jnano/
wget https://download.qt.io/archive/qt/5.9/5.9.5/single/qt-everywhere-opensource-src-5.9.5.tar.xz
tar -xf qt-everywhere-opensource-src-5.9.5.tar.xz
拷贝Jetson Nano中的必要文件至虚拟机的sysroot:
rsync -avz [email protected]:/usr ~/qt_jnano/sysroot
rsync -avz [email protected]:/lib ~/qt_jnano/sysroot
#我担心会出现拷贝不完整的问题,将usr文件夹下的全部内容都拷贝了,如果不想这么做可以尝试:
rsync -avz [email protected]:/usr/inlcude ~/qt_jnano/sysroot/usr
rsync -avz [email protected]:/usr/lib ~/qt_jnano/sysroot/usr
rsync -avz [email protected]:/lib ~/qt_jnano/sysroot
下载并运行路径同步脚本:
地址:sysroot-relativelinks.py
cd ~/qt_jnano
sudo chmod +x sysroot-relativelinks.py
python3 sysroot-relativelinks.py sysroot
重复以上步骤(拷贝Jetson Nano中的必要文件至虚拟机的sysroot)。
在qt源码中为Jetson Nano配置qmake:
cp /home/smuvision/qt_jnano/qt-everywhere-opensource-src- 5.9.5/qtbase/mkspecs/devices/linux-jetson-tx1-g++ /home/smuvision/qt_jnano/qt-everywhere-opensource-src-5.9.5/qtbase/mkspecs/devices/linux-jetson-nano
vim /home/smuvision/qt_jnano/qt-everywhere-opensource-src-5.9.5/qtbase/mkspecs/devices/linux-jetson-nano/qmake.conf
##################################将文本替换为如下内容:###################################
#
# qmake configuration for the Jetson Nano
#
# Note that this environment has been tested with X11 only.
#
# A typical configure line might look like:
# configure \
# -device linux-jetson-nano \
# -device-option CROSS_COMPILE=/home/smuvision/qt_jnano/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- \
# -sysroot /home/smuvision/qt_jnano/sysroot
include(../common/linux_device_pre.conf)
QMAKE_INCDIR_POST += \
$$[QT_SYSROOT]/usr/include \
$$[QT_SYSROOT]/usr/include/aarch64-linux-gnu
QMAKE_LIBDIR_POST += \
$$[QT_SYSROOT]/usr/lib \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu
QMAKE_RPATHLINKDIR_POST += \
$$[QT_SYSROOT]/usr/lib \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu
QMAKE_INCDIR_EGL = $$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu/tegra-egl
DISTRO_OPTS += aarch64
COMPILER_FLAGS += -march=armv8-a+crypto+crc
EGLFS_DEVICE_INTEGRATION = eglfs_kms_egldevice
include(../common/linux_arm_device_post.conf)
load(qt_config)
#########################################################################################
配置qt源码编译选项,以及编译:
cd ~/qt_jnano/qt5build
#下面是我的配置选项,qt creator对我而言只是编译工具,我不需要任何qt自带的库,如果有需要,可以通过configure --help 来选择你所需的配置。但是不同的配置会有很大概率造成编译报错,需要根据报错信息逐个排查,有一定难度。
../qt-everywhere-opensource-src-5.9.5/configure -prefix /usr/local/linux-jetson-nano -confirm-license -opensource -device linux-jetson-nano -device-option CROSS_COMPILE=/home/smuvision/qt_jnano/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -sysroot /home/smuvision/qt_jnano/sysroot -no-opengl -skip qtscript -skip wayland -skip qtwebengine -force-debug-info -skip qtdatavis3d -skip qtlocation -nomake examples -make libs -pkg-config -no-use-gold-linker -v -no-openssl -shared -release -pch -no-cups -no-glib -no-dbus -no-xcb -no-separate-debug-info -no-fontconfig -nomake tests -no-iconv -no-tslib
#还有一种方法就是在../qt-everywhere-opensource-src-5.9.5/qtbase中编译,可以不附带任何qt库,比较纯净,但是我没有验证过。
make
make install
#注意!!!
#如果需要重新配置选项,需要将qt5build中的文件清空后,再重新配置。
#如果出现编译失败的情况,一定要先删除交叉编译工具链和qt源码,然后重新解压后重复之前的操作。
拷贝虚拟机中的编译好的文件至Jetson Nano:
rsync -avz ~/qt_jnano/sysroot/usr/local/linux-jetson-nano [email protected]:/home/smuvision
sudo mv -r ~/linux-jetson-nano /usr/local
配置QT Creator中的交叉编译工具:
(Tools->Options->Devices->Add->Generic Linux Device)
按步骤填写Jetson Nano的相关信息即可。
(Tools->Options->Build&Run)
交叉编译工具使用:
$$[QT_SYSROOT]
TARGET = TruckDetect_Cross
target.path = /home/smuvision/work/Truck/build-TruckDetect-Desktop-Debug
INSTALLS += target
说明:
可能出现的问题以及解决方法:
解决方法:
#远程打开图像窗口需要访问X11 server,访问X11 server我们需要两个东西:DISPLAY和XAUTHORITY两个环境变量。但是,由于它们在不同的发型版和Display Manager下都有些不同,所以需要下面的操作来获取:
DISPLAY=$(w -hs | awk 'match($2, /:[0-9]+/) {print $2; exit}')
#下面的指令会出现用户名显示不全的问题,通过USER=**代替(**为你的用户名)
USER=$(w -hs | awk 'match($2, /:[0-9]+/) {print $1; exit}')
eval XAUTHORITY=/run/user/$(id -u $USER)/gdm/Xauthority
export DISPLAY
export XAUTHORITY
DIMENSIONS=$(xdpyinfo | grep 'dimensions:' | awk '{print $2;exit}')
解决方法: 在main函数开头添加:
#由于打印消息已经被输出到stdout的缓冲区之中,如果把缓冲区的大小设置成0,日志就可以直接输出
setbuf(stdout, NULL);
解决方法:需要单独把缺失文件的路径包含进去。