linuxdeployqt icon indicating copy to clipboard operation
linuxdeployqt copied to clipboard

ARM32 cross-compile problem

Open haroldsamuels87 opened this issue 1 year ago • 0 comments

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:

  1. 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)
  2. 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?
  3. what is $ORIGIN in shared.cpp, I couldn't find any documentation on that.

Thanks

haroldsamuels87 avatar Jul 07 '22 14:07 haroldsamuels87