本文主要介绍在ubuntu22.04主机上搭建qt交叉编译环境教程,方便在上位机开发下位机应用程序
$ uname -a
Linux yz-MS-7E06 6.8.0-45-generic #45~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Sep 11 15:25:05 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
$ pwd
/home/yz/qt5.15.15
$ ls
aarch64--glibc--stable-2022.08-1 qt-everywhere-opensource-src-5.15.15.tar.xz
aarch64--glibc--stable-2022.08-1.tar.bz2 qt-everywhere-src-5.15.15
linux-jetson-nx sysroot
linux-jetson-nx.zip Tegra_Linux_Sample-Root-Filesystem_R36.4.0_aarch64.tbz2
qt-creator-opensource-linux-x86_64-10.0.2.run
$ mv linux-jetson-nx ./qt-everywhere-src-5.15.15/qtbase/mkspecs/devices/
#!/usr/bin/env python
import sys
import os
# Take a sysroot directory and turn all the abolute symlinks and turn them into
# relative ones such that the sysroot is usable within another system.
if len(sys.argv) != 2:
print("Usage is " + sys.argv[0] + "" )
sys.exit(1)
topdir = sys.argv[1]
topdir = os.path.abspath(topdir)
def handlelink(filep, subdir):
link = os.readlink(filep)
if link[0] != "/":
return
if link.startswith(topdir):
return
#print("Replacing %s with %s for %s" % (link, topdir+link, filep))
print("Replacing %s with %s for %s" % (link, os.path.relpath(topdir+link, subdir), filep))
os.unlink(filep)
os.symlink(os.path.relpath(topdir+link, subdir), filep)
for subdir, dirs, files in os.walk(topdir):
for f in files:
filep = os.path.join(subdir, f)
if os.path.islink(filep):
#print("Considering %s" % filep)
handlelink(filep, subdir)
运行如下命令:
$ ./sysroot-relativelinks.py ./sysroot
vim ~/.bashrc
export PATH=$PATH:~/qt5.15.15/aarch64--glibc--stable-2022.08-1/bin
source ~/.bashrc
#!/bin/bash
echo "start build"
../qt-everywhere-src-5.15.15/configure -release -opengl es2 \
-device linux-jetson-nx \
-device-option CROSS_COMPILE=aarch64-linux- \
-sysroot $HOME/qt5.15.15/sysroot \
-prefix /usr/local/qt5 \
-opensource -confirm-license \
-skip qtscript \
-skip wayland \
-skip qtwebengine \
-force-debug-info -skip qtlocation \
-nomake examples \
-nomake tests \
-make libs \
-pkg-config -no-use-gold-linker -v
make -j24
,大概25分钟左右编译完毕make install
小编在编译中碰见如下的问题,希望给大家提供一种解决方案
> /home/yz/qt5.15.15/aarch64--glibc--stable-2022.08-1/bin/../lib/gcc/aarch64-buildroot-linux-gnu/11.3.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: cannot find Scrt1.o: No such file or directory
> /home/yz/qt5.15.15/aarch64--glibc--stable-2022.08-1/bin/../lib/gcc/aarch64-buildroot-linux-gnu/11.3.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: cannot find crti.o: No such file or directory
> > /home/yz/qt5.15.15/aarch64--glibc--stable-2022.08-1/bin/../lib/gcc/aarch64-buildroot-linux-gnu/11.3.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: cannot find Scrt1.o: No such file or directory
问题分析:在sysroot中找不到对应的链接,可以进行手动链接
cd ./sysroot/usr/lib
ln -sf ./aarch64-linux-gnu/crti.o crti.o
ln -sf ./aarch64-linux-gnu/crt1.o crt1.o
ln -sf ./aarch64-linux-gnu/crtn.o crtn.o
ln -sf ./aarch64-linux-gnu/Scrt1.o Scrt1.o
/home/yz/qt5.15.15/sysroot
/home/yz/qt5.15.15/aarch64--glibc--stable-2022.08-1/bin/aarch64-linux-gcc
/home/yz/qt5.15.15/aarch64--glibc--stable-2022.08-1/bin/aarch64-linux-g++
/home/yz/qt5.15.15/sysroot/usr/local/qt5/bin/qmake
$ file untitled
untitled: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, with debug_info, not stripped
$ tree
.
├── hello.cu
├── hello.cuh
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
└── MemsTest.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
hello.cuh \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
###########################CUDA CONFIG####################################
#配置cuda的头文件和相关库的路径
LIBS += -L'/usr/local/cuda-11.4/targets/aarch64-linux/lib' -lcudart
INCLUDEPATH += '/usr/local/cuda-11.4/targets/aarch64-linux/include'
DEPENDPATH += '/usr/local/cuda-11.4/targets/aarch64-linux/lib'
INCLUDEPATH += './'
CUDA_DIR="/usr/local/cuda-11.4"
CUDA_SDK="/usr/local/cuda-11.4"
QMAKE_LIBDIR += $$CUDA_DIR/targets/aarch64-linux/lib
NVCCFLAGS = --use_fast_math
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
# MSVCRT link option (static or dynamic, it must be the same with your Qt SDK link option)
CUDA_OBJECTS_DIR = ./
CUDA_SOURCES+=./hello.cu
CONFIG(debug, debug|release) {
# Debug mode
cuda_d.input = CUDA_SOURCES
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}.o
cuda_d.commands = $$CUDA_DIR/bin/nvcc --device-debug --debug -gencode arch=compute_86,code=sm_86 -gencode arch=compute_86,code=compute_86 -ccbin $$QMAKE_CXX \
-c ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT}
cuda_d.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda_d
}
else {
# Release mode
cuda.input = CUDA_SOURCES
cuda.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}.o
cuda.commands = $$CUDA_DIR/bin/nvcc --cudart=static -ccbin $$QMAKE_CXX -gencode arch=compute_86,code=sm_86 -gencode arch=compute_86,code=compute_86 \
-c ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT}
cuda.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda
}
#include
#include
#include "hello.cuh"
__global__ void hello(){
int i = blockDim.x * blockIdx.x + threadIdx.x;
printf("hello %d\n",i);
}
int test_cuda(void){
hello<<<1, 3>>>();
cudaDeviceSynchronize();
printf("Done \n");
return 0;
}
#include "mainwindow.h"
#include
#include "hello.cuh"
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
test_cuda();
int runtimeVersion;
int deviceCount;
cudaError_t err = cudaRuntimeGetVersion(&runtimeVersion);
if (err == cudaSuccess) {
std::cout << "CUDA Runtime Version: " << (runtimeVersion / 1000) << "."
<< (runtimeVersion % 100) << std::endl;
} else {
std::cerr << "Failed to get CUDA runtime version: "
<< cudaGetErrorString(err) << std::endl;
}
err = cudaGetDeviceCount(&deviceCount);
if (err == cudaSuccess) {
std::cout << "Detected " << deviceCount << " CUDA Capable device(s)."
<< std::endl;
} else {
std::cerr << "Error: " << cudaGetErrorString(err)
<< " when trying to get CUDA device count." << std::endl;
}
MainWindow w;
w.show();
return a.exec();
}
file MemsTest
MemsTest: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, with debug_info, not stripped
当将编译环境sysroot拷贝到另外的电脑开发环境中,需要修改相关的qt.conf
来解决qmake
识别不到版本问题
在sysroot/usr/local/qt5/bin
配置qt.conf
配置如下:
[Paths]
Prefix=/usr/local/qt5
HostPrefix=~/test/sysroot/usr/local/qt5
Sysroot=~/test/sysroot
TargetSpec=devices/linux-jetson-nx
注意上面的HostPrefix
和Sysroot
与SDK路径一致
https://gitcode.com/YYRAN_ZZU/QtJetsonCrossCompilationExample.git