linuxdeployqt
linuxdeployqt copied to clipboard
ARM32 cross-compile problem
Hi, I am cross-compiling a Qt program for arm32 on an amd64 machine (with docker) and I want it to be deployed with linuxdeployqt. I use ubuntu base image and apt-get to install necessary qt libraries. here is my Dockerfile:
FROM --platform=linux/arm/v7 ubuntu:jammy
RUN apt-get update
RUN export DEBIAN_FRONTEND=noninteractiv && \
apt -y install build-essential cmake git \
gdb wget curl nano file patchelf \
qtbase5-dev libqt5qml5 qtdeclarative5-dev \
qml-module-qtquick2 qml-module-qtquick-window2 qml-module-qtquick-controls2
RUN cd /home && \
git clone https://github.com/probonopd/linuxdeployqt.git && cd linuxdeployqt && \
git checkout continuous && \
export PATH=$(readlink -f /tmp/.mount_QtCreator-*-x86_64/*/gcc_64/bin/):$PATH && \
cd /home/linuxdeployqt && \
qmake && \
make -j$(nproc) && sudo make install
RUN wget -c \
"https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-armhf.AppImage" \
-O /usr/local/bin/appimagetool && \
chmod a+x /usr/local/bin/appimagetool
I used patchelf v0.14 because patchelf v0.9 was damaging the main executable, it gave me a warning with following message: creating a hole of ~50KB to work around a linux kernel bug. my program compiles successfully and if I copy it to the arm32 machine, it just works fine. now when I try to use linuxdeployqt with the folowing command :
linuxdeployqt <EXECUTABLE> -no-translations -unsupported-allow-new-glibc -appimage -qmldir=<PATH> -no-copy-copyright-files -no-strip
I see this error:
ERROR: Could not parse ldd output under 2 lines: ""
QProcess: Destroyed while process ("ldd") is still running.
QProcess: Destroyed while process ("objdump") is still running.
I inspected the code and I figured out that the QProcess is malfunctioning. if I use ldd
on my program it shows dependencies correctly.
I created a simple program to test QProcess and again it just did not work with any type of command. I searched the internet and couldn't find any solution to this problem so I decided to change the code and I came with this temporary solution.
I created a function to open a process with popen
instead of QProcess :
QByteArray q_process_alternative(const QString &command, const QStringList &arguments){
QByteArray ret_val;
FILE *fp;
char line[200];
char command_str[5000];
sprintf(command_str,"%s %s", command.toLocal8Bit().data(), arguments.join(" ").toLocal8Bit().data());
printf("command_str->%s\n",command_str );
fp = popen(command_str, "r");
while ( fgets( line, sizeof line, fp))
{
ret_val += QByteArray::fromRawData(line, strlen(line));
}
pclose(fp);
return ret_val;
}
I know it's not an efficient alternative but I wanted an ad-hoc and quick solution and it worked with ldd but patchelf complains about missing filename
. patchelf issues a command like this line:
patchelf $ORIGIN /path/to/libQtX.so.x
I could not find out what this $ORIGIN
is and what it does. Can anybody please help me with that?
To Summarize I have these questions:
- How to fix QProcess problem on an emulated docker container?(in my case host machine is amd64 and target is arm32 and I use qemu-arm-static)
- If it's not possible to fix QProcess problem, How can I write a QProcess alternative for
shared.cpp
and is this the correct way? - what is
$ORIGIN
inshared.cpp
, I couldn't find any documentation on that.
Thanks