Host: Ubuntu 20.04 x64
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
Address sizes: 43 bits physical, 48 bits virtual
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: AuthenticAMD
CPU family: 23
Model: 32
Model name: AMD Athlon Silver 3050e with Radeon Graphics
Stepping: 1
Frequency boost: enabled
CPU MHz: 946.324
CPU max MHz: 1400,0000
CPU min MHz: 1000,0000
BogoMIPS: 2794.78
Virtualization: AMD-V
L1d cache: 64 KiB
L1i cache: 128 KiB
L2 cache: 1 MiB
L3 cache: 4 MiB
NUMA node0 CPU(s): 0-3
Vulnerability Itlb multihit: Not affected
Vulnerability L1tf: Not affected
Vulnerability Mds: Not affected
Vulnerability Meltdown: Not affected
Vulnerability Mmio stale data: Not affected
Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled v
ia prctl and seccomp
Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user
pointer sanitization
Vulnerability Spectre v2: Mitigation; Retpolines, IBPB conditional, STIBP
always-on, RSB filling
Vulnerability Srbds: Not affected
Vulnerability Tsx async abort: Not affected
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtr
r pge mca cmov pat pse36 clflush mmx fxsr sse s
se2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtsc
p lm constant_tsc rep_good nopl nonstop_tsc cpu
id extd_apicid aperfmperf pni pclmulqdq monitor
ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes
xsave avx f16c rdrand lahf_lm cmp_legacy svm ex
tapic cr8_legacy abm sse4a misalignsse 3dnowpre
fetch osvw skinit wdt tce topoext perfctr_core
perfctr_nb bpext perfctr_llc mwaitx cpb hw_psta
te sme ssbd sev ibpb stibp vmmcall fsgsbase bmi
1 avx2 smep bmi2 rdseed adx smap clflushopt sha
_ni xsaveopt xsavec xgetbv1 xsaves clzero irper
f xsaveerptr arat npt lbrv svm_lock nrip_save t
sc_scale vmcb_clean flushbyasid decodeassists p
ausefilter pfthreshold avic v_vmsave_vmload vgi
f overflow_recov succor smca
Target: Raspberry Pi 4 with Ubuntu 22.04 x64
Architecture: aarch64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Vendor ID: ARM
Model name: Cortex-A72
Model: 3
Thread(s) per core: 1
Core(s) per cluster: 4
Socket(s): -
Cluster(s): 1
Stepping: r0p3
CPU max MHz: 1800,0000
CPU min MHz: 600,0000
BogoMIPS: 108.00
Flags: fp asimd evtstrm crc32 cpuid
Caches (sum of all):
L1d: 128 KiB (4 instances)
L1i: 192 KiB (4 instances)
L2: 1 MiB (1 instance)
Vulnerabilities:
Itlb multihit: Not affected
L1tf: Not affected
Mds: Not affected
Meltdown: Not affected
Spec store bypass: Vulnerable
Spectre v1: Mitigation; __user pointer sanitization
Spectre v2: Vulnerable
Srbds: Not affected
Tsx async abort: Not affected
Main questions:
- What is the best cross-platform compiler to use for this purpose given the architecture processors? (https://releases.linaro.org/components/toolchain/binaries/latest-7/)
- In most of the guides,
rsync
is performed between a host on Ubuntu and a target on Raspbian. What directories need to be synchronized if both computers are on Ubuntu? - What parameters should be input to the
./config
command before Qt5 compiling? - There is no targeted device Pi 4 in
/mkspecs/devices
of Qt 5.12.12,
there are only variations of Pi 3. What targeted device from this list should be chosen?
2
Answers
I think you should start off by installing the gcc-aarch64-linux-gnu package.
Cross-compiling Qt for Linux is a huge undertaking because it relies on a large number of X libraries which it uses to talk to the X windows system. You will need to compile each of these libraries in the correct order and install them to a directory somewhere which you use to store aarch64 binaries. When you finally succeed in building a Qt program, you will need to transfer all the
.so
files (dynamic libraries) that your program relies on to the target machine. Or compile everything as a static library.For what it’s worth, I have cross-compiled Qt as a static library for Linux before and successfully used it to make standalone GUI applications. But I was only targeting 32-bit ARM, x86, and x86_64. My code mostly consists of Nix expressions and shell scripts and you can find it here: https://github.com/DavidEGrayson/nixcrpkgs/blob/master/pkgs/qt/default.nix
In the code I linked to, the term "libxall" refers to a bundle I made with "all" the X libraries. The list of libraries I included is:
Some of these libraries depend on others, so I had to compile them in the correct order and provide the right configuration options so that they get cross-compiled using the cross compiler and can find their dependenceis.
You shouldn’t just blindly trust my list of X libraries: things might have changed since I did that work a few years ago. The Qt configuration script will tell you what libraries it needs by printing informative error messages when such a library is missing. When you see such an error message, then you need to find that library and cross-compile it using your cross-compiler and try again. Eventually, after you have fixed every error message, you might get something that works. It’s pretty much impossible for me to tell you exactly what you need to do unless I sat down and did all the work myself using the same versions of Ubuntu and Qt.
When I cross-compiled Qt for Linux, the device I configured it for was "devices/linux-generic" (
-xplatform devices/linux-generic
). So I would try that one first unless you see another options that looks like a closer fit for your Raspberry Pi.Alternative idea: Instead of compiling a dozen libraries and Qt yourself, maybe you can just install Qt and the relevant libraries on your Raspberry Pi using its package manager, transfer them to your x86 Ubuntu machine using rsync, and then use the cross-compiler to just compile your app. But when you invoke the cross-compile you must use the correct
-I
,-L
, and-l
options so it can find the header files and libraries it needs.I will try to answer based on my previous experience cross-compiling Qt 6.
I agree with David that you should start off by installing
gcc-aarch64-linux-gnu
from Ubuntu package manager on your host machine. In my experience, it is the easiest way to cross-compile for Aarch64 target on Ubuntu/Debian-based host. I tried other compilers and toolchains from Linaro and ARM but I found them too much hassle to work with because they’re either outdated or just doesn’t work with Aarch64 architecture.I used
rsync
mainly to build a sysroot of my target in host device. This includes/lib
,/usr/include
,/usr/lib
, and/opt/vc
(though my Raspberry Pi doesn’t have/opt/vc
but it seems to compile Qt just fine).Configuration parameters for compiling Qt 6 and Qt 5 are pretty different, so I can’t say much on this matter. I’d imagine parameters that this guide or this one used would work fine to cross-compile Qt 5, but in case you’re interested to use Qt 6 I recently wrote this (sorry for the shameless plug).
For question 4, I don’t really know which one works for Raspberry Pi 4 on Qt 5.12.12. I agree with David again that you can try
devices/linux-generic
mkspecs to start with and see if it suits you.