Making an Appimage

Building an Appimage for Qt Application

When I updated to Ubuntu 24.04 I had an upsetting number of packages break. One of these was AppCSXCAD. It reads OpenEMS XML geometry files and shows them in a GUI. Nothing exciting until you need it. My first move was making sure I could use the Dockerized version in my OpenEMS Docker build here. That needed some attention but it worked in the end. What I really want is an appimage that I can pull down when needed.

After trying to compose one by hand and running into issues with Qt I found a great tool that solved the problem probonopd/linuxdeployqt. It takes care of the tricky parts leaving us with the following Docker image:

FROM ubuntu:22.04 AS builder
ENV DEBIAN_FRONTEND=noninteractive
# Install all required packages
RUN apt-get update && apt-get install -y --no-install-recommends \
    git wget build-essential cmake pkg-config \
    libx11-dev x11-apps paraview \
    libhdf5-dev libvtk7-dev libvtk7-qt-dev \
    libboost-all-dev libcgal-dev libtinyxml-dev \
    qtbase5-dev octave liboctave-dev \
    gengetopt help2man groff pod2pdf bison flex libhpdf-dev libtool \
    python3.10 python3-pip python3-dev python3-tk vim imagemagick\
    fonts-dejavu-core \
    && rm -rf /var/lib/apt/lists/*

# Upgrade pip and install Python tools
RUN pip install --upgrade pip wheel setuptools==58.2.0 pyproject-toml

# Clone OpenEMS project
WORKDIR /root/
ARG BRANCH=v0.0.36.alpha2
ARG REPO=https://github.com/snhobbs/OpenEMS-Project.git

RUN git clone --recursive --branch ${BRANCH} ${REPO}

# Build all components
WORKDIR /root/OpenEMS-Project/fparser
RUN cmake . && make -j$(nproc) && make install

WORKDIR /root/OpenEMS-Project/CSXCAD
RUN cmake . && make -j$(nproc) && make install

WORKDIR /root/OpenEMS-Project/QCSXCAD
RUN cmake . && make -j$(nproc) && make install

WORKDIR /root/OpenEMS-Project/AppCSXCAD
RUN cmake . && make -j$(nproc) && make install

# Download and prepare linuxdeployqt
WORKDIR /root/

RUN wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage && \
    chmod 775 linuxdeployqt-continuous-x86_64.AppImage && \
    ./linuxdeployqt-continuous-x86_64.AppImage --appimage-extract && \
    mv squashfs-root/ linuxdeployqt-continuous

# Setup AppImage structure
WORKDIR /root/appimage
RUN mkdir -p local/bin && cp /usr/local/bin/AppCSXCAD local/bin

# Generate a basic icon and desktop file
RUN convert -size 256x256 xc:white -gravity center \
  -font DejaVu-Sans -pointsize 24 -annotate 0 "AppCSXCAD" appcsxcad.png

RUN echo "[Desktop Entry]\n\
Type=Application\n\
Name=AppCSXCAD\n\
Exec=AppRun %F\n\
Icon=appcsxcad\n\
Comment=View and edit OpenEMS Geometries\n\
Terminal=true\n\
Categories=Education;Science;" > default.desktop

# Use linuxdeploy to populate dependencies (this assumes Qt app)
RUN /root/linuxdeployqt-continuous/AppRun /root/appimage/local/bin/AppCSXCAD -appimage -bundle-non-qt-libs -verbose=2

# Copy final artifact to a known location
RUN mkdir -p /output && cp /root/appimage/*.AppImage /output/

# ---- Stage 2: Minimal stage that just contains the AppImage output ----
FROM scratch AS export-stage
COPY --from=builder /output /output

Build it with:

docker build -f Dockerfile -t appcsxcad-appimage --output type=local,dest=./ .

Once this runs it produces the AppImage in ./output/.

Should make OpenEMS development a bit easier. I’ll make this a github action at some point.

Another useful project: https://github.com/AppImage/AppImageKit/releases/latest/download/appimagetool-x86_64.AppImage